Added preliminary support for image templates. Not finished yet. Addresses

2003-04-03  Michael Natterer  <mitch@gimp.org>

	Added preliminary support for image templates. Not finished
	yet. Addresses bug #96059. Now we need a volunteer to create
	a nice collection of default templates...

	* app/core/Makefile.am
	* app/core/core-types.h
	* app/core/gimptemplate.[ch]
	* app/core/gimp-templates.[ch]: new files implementing the new
	GimpTemplate object and the list of available image templates.

	* app/core/gimp.[ch]: keep a container of templates around.

	* app/core/gimpimage-new.[ch]: ported to use GimpTemplate. Removed
	struct GimpImageNewValues.

	* app/widgets/gimpcontainermenuimpl.c: changed to show the
	"(none)" item for a NULL selection also, not only for an empty
	container.

	* app/widgets/gimppropwidgets.[ch]: added
	gimp_prop_size_entry_connect() which connects an externally
	created GimpSizeEntry to object properties. Fixed the size entry
	code to actually work.

	* app/gui/image-menu.c
	* app/gui/file-commands.[ch]: added "Save as Template" which
	creates a new template from any image's properties.

	* app/gui/file-new-dialog.c: use prop_widgets and GimpTemplate.
	Offer the available templates in a menu at the top of the dialog.
This commit is contained in:
Michael Natterer 2003-04-03 17:50:56 +00:00 committed by Michael Natterer
parent 4865105f41
commit a018b06a96
24 changed files with 1338 additions and 835 deletions

View File

@ -1,3 +1,36 @@
2003-04-03 Michael Natterer <mitch@gimp.org>
Added preliminary support for image templates. Not finished
yet. Addresses bug #96059. Now we need a volunteer to create
a nice collection of default templates...
* app/core/Makefile.am
* app/core/core-types.h
* app/core/gimptemplate.[ch]
* app/core/gimp-templates.[ch]: new files implementing the new
GimpTemplate object and the list of available image templates.
* app/core/gimp.[ch]: keep a container of templates around.
* app/core/gimpimage-new.[ch]: ported to use GimpTemplate. Removed
struct GimpImageNewValues.
* app/widgets/gimpcontainermenuimpl.c: changed to show the
"(none)" item for a NULL selection also, not only for an empty
container.
* app/widgets/gimppropwidgets.[ch]: added
gimp_prop_size_entry_connect() which connects an externally
created GimpSizeEntry to object properties. Fixed the size entry
code to actually work.
* app/gui/image-menu.c
* app/gui/file-commands.[ch]: added "Save as Template" which
creates a new template from any image's properties.
* app/gui/file-new-dialog.c: use prop_widgets and GimpTemplate.
Offer the available templates in a menu at the top of the dialog.
2003-04-03 Michael Natterer <mitch@gimp.org>
* app/tools/gimpmovetool.c (gimp_move_tool_button_release): don't

View File

@ -18,6 +18,8 @@
#include "config.h"
#include <string.h>
#include <gtk/gtk.h>
#include "libgimpwidgets/gimpwidgets.h"
@ -31,7 +33,7 @@
#include "core/gimpcontext.h"
#include "core/gimpimage.h"
#include "core/gimpimage-undo.h"
#include "core/gimpobject.h"
#include "core/gimptemplate.h"
#include "file/file-open.h"
#include "file/file-save.h"
@ -77,6 +79,9 @@
/* local function prototypes */
static void file_new_template_callback (GtkWidget *widget,
gchar *name,
gpointer data);
static void file_revert_confirm_callback (GtkWidget *widget,
gboolean revert,
gpointer data);
@ -264,6 +269,25 @@ file_save_a_copy_cmd_callback (GtkWidget *widget,
file_save_a_copy_dialog_show (gdisp->gimage, global_menu_factory);
}
void
file_save_template_cmd_callback (GtkWidget *widget,
gpointer data,
guint action)
{
GimpDisplay *gdisp;
GtkWidget *qbox;
return_if_no_display (gdisp, data);
qbox = gimp_query_string_box (_("Create New Template"),
gimp_standard_help_func,
"dialogs/new_template.html",
_("Enter a name for this template"),
NULL,
G_OBJECT (gdisp->gimage), "disconnect",
file_new_template_callback, gdisp->gimage);
gtk_widget_show (qbox);
}
void
file_revert_cmd_callback (GtkWidget *widget,
gpointer data,
@ -354,8 +378,30 @@ file_file_open_dialog (Gimp *gimp,
file_open_dialog_show (gimp, NULL, uri, global_menu_factory);
}
/* private functions */
static void
file_new_template_callback (GtkWidget *widget,
gchar *name,
gpointer data)
{
GimpTemplate *template;
GimpImage *gimage;
gimage = (GimpImage *) data;
if (! (name && strlen (name)))
name = _("(Unnamed Template)");
template = gimp_template_new (name);
gimp_template_set_from_image (template, gimage);
gimp_container_add (gimage->gimp->templates,
GIMP_OBJECT (template));
g_object_unref (template);
}
static void
file_revert_confirm_callback (GtkWidget *widget,
gboolean revert,

View File

@ -52,6 +52,9 @@ void file_save_as_cmd_callback (GtkWidget *widget,
void file_save_a_copy_cmd_callback (GtkWidget *widget,
gpointer data,
guint action);
void file_save_template_cmd_callback (GtkWidget *widget,
gpointer data,
guint action);
void file_revert_cmd_callback (GtkWidget *widget,
gpointer data,

View File

@ -28,6 +28,8 @@ libappcore_a_sources = \
gimp-gradients.h \
gimp-parasites.c \
gimp-parasites.h \
gimp-templates.c \
gimp-templates.h \
gimpbrush.c \
gimpbrush.h \
gimpbrush-header.h \
@ -156,6 +158,8 @@ libappcore_a_sources = \
gimppreviewcache.h \
gimpscanconvert.c \
gimpscanconvert.h \
gimptemplate.c \
gimptemplate.h \
gimptoolinfo.c \
gimptoolinfo.h \
gimpunit.c \

View File

@ -73,6 +73,8 @@ typedef struct _GimpToolOptions GimpToolOptions; /*< proxy-include >*/
typedef struct _GimpImagefile GimpImagefile;
typedef struct _GimpDocumentList GimpDocumentList;
typedef struct _GimpTemplate GimpTemplate;
/* drawable objects */
@ -122,8 +124,6 @@ typedef struct _GimpCoords GimpCoords; /*< proxy-include >*/
typedef struct _GimpGuide GimpGuide;
typedef struct _GimpImageNewValues GimpImageNewValues;
typedef struct _GimpProgress GimpProgress;
typedef guint32 GimpTattoo;

87
app/core/gimp-templates.c Normal file
View File

@ -0,0 +1,87 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995-1997 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 <glib-object.h>
#include "libgimpbase/gimpbase.h"
#include "core-types.h"
#include "config/gimpconfig.h"
#include "gimp.h"
#include "gimp-templates.h"
#include "gimplist.h"
#include "gimptemplate.h"
/* functions to load and save the gimp templates files */
void
gimp_templates_load (Gimp *gimp)
{
gchar *filename;
GError *error = NULL;
g_return_if_fail (GIMP_IS_GIMP (gimp));
g_return_if_fail (GIMP_IS_LIST (gimp->templates));
filename = gimp_personal_rc_file ("templates");
if (!gimp_config_deserialize (G_OBJECT (gimp->templates),
filename,
NULL,
&error))
{
if (error->code != GIMP_CONFIG_ERROR_OPEN_ENOENT)
g_message (error->message);
g_error_free (error);
}
g_free (filename);
}
void
gimp_templates_save (Gimp *gimp)
{
const gchar *header =
"GIMP templates\n"
"\n"
"This file will be entirely rewritten every time you quit the gimp.";
const gchar *footer =
"end of templates";
gchar *filename;
GError *error = NULL;
g_return_if_fail (GIMP_IS_GIMP (gimp));
g_return_if_fail (GIMP_IS_LIST (gimp->templates));
filename = gimp_personal_rc_file ("templates");
if (! gimp_config_serialize (G_OBJECT (gimp->templates),
filename, header, footer, NULL, &error))
{
g_message (error->message);
g_error_free (error);
}
g_free (filename);
}

27
app/core/gimp-templates.h Normal file
View File

@ -0,0 +1,27 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995-1997 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.
*/
#ifndef __GIMP_TEMPLATES_H__
#define __GIMP_TEMPLATES_H__
void gimp_templates_load (Gimp *gimp);
void gimp_templates_save (Gimp *gimp);
#endif /* __GIMP_TEMPLATES_H__ */

View File

@ -44,6 +44,7 @@
#include "gimp-documents.h"
#include "gimp-gradients.h"
#include "gimp-parasites.h"
#include "gimp-templates.h"
#include "gimpbrush.h"
#include "gimpbrushgenerated.h"
#include "gimpbrushpipe.h"
@ -62,6 +63,7 @@
#include "gimppalette.h"
#include "gimppattern.h"
#include "gimpparasitelist.h"
#include "gimptemplate.h"
#include "gimptoolinfo.h"
#include "gimpunits.h"
@ -251,6 +253,9 @@ gimp_init (Gimp *gimp)
gimp->documents = gimp_document_list_new (gimp);
gimp->templates = gimp_list_new (GIMP_TYPE_TEMPLATE,
GIMP_CONTAINER_POLICY_STRONG);
gimp->image_new_last_template = NULL;
gimp->have_current_cut_buffer = FALSE;
gimp->context_list = NULL;
@ -299,6 +304,18 @@ gimp_finalize (GObject *object)
gimp->standard_context = NULL;
}
if (gimp->image_new_last_template)
{
g_object_unref (gimp->image_new_last_template);
gimp->image_new_last_template = NULL;
}
if (gimp->templates)
{
g_object_unref (gimp->templates);
gimp->templates = NULL;
}
if (gimp->documents)
{
g_object_unref (gimp->documents);
@ -466,7 +483,9 @@ gimp_get_memsize (GimpObject *object)
memsize += (gimp_object_get_memsize (GIMP_OBJECT (gimp->tool_info_list)) +
gimp_object_get_memsize (GIMP_OBJECT (gimp->standard_tool_info)) +
gimp_object_get_memsize (GIMP_OBJECT (gimp->documents)));
gimp_object_get_memsize (GIMP_OBJECT (gimp->documents)) +
gimp_object_get_memsize (GIMP_OBJECT (gimp->templates)) +
gimp_object_get_memsize (GIMP_OBJECT (gimp->image_new_last_template)));
memsize += g_list_length (gimp->context_list) * sizeof (GList);
@ -487,6 +506,7 @@ gimp_real_exit (Gimp *gimp,
gimp_data_factory_data_save (gimp->gradient_factory);
gimp_data_factory_data_save (gimp->palette_factory);
gimp_documents_save (gimp);
gimp_templates_save (gimp);
gimp_parasiterc_save (gimp);
gimp_unitrc_save (gimp);
@ -690,15 +710,8 @@ gimp_initialize (Gimp *gimp,
/* Set the last values used to default values. */
gimp->image_new_last_values.width = gimp->config->default_image_width;
gimp->image_new_last_values.height = gimp->config->default_image_height;
gimp->image_new_last_values.unit = gimp->config->default_unit;
gimp->image_new_last_values.xresolution = gimp->config->default_xresolution;
gimp->image_new_last_values.yresolution = gimp->config->default_yresolution;
gimp->image_new_last_values.res_unit = gimp->config->default_resolution_unit;
gimp->image_new_last_values.type = gimp->config->default_image_type;
gimp->image_new_last_values.fill_type = GIMP_BACKGROUND_FILL;
gimp->image_new_last_template = gimp_template_new ("last values");
gimp_template_set_from_config (gimp->image_new_last_template, gimp->config);
gimp->have_current_cut_buffer = FALSE;
gimp->standard_context = gimp_context_new (gimp, "Standard", NULL);
@ -762,15 +775,19 @@ gimp_restore (Gimp *gimp,
gimp_data_factory_data_init (gimp->gradient_factory, no_data);
/* initialize the list of gimp fonts */
(* status_callback) (NULL, _("Fonts"), 0.75);
(* status_callback) (NULL, _("Fonts"), 0.70);
gimp_container_freeze (gimp->fonts);
gimp_font_list_restore (GIMP_FONT_LIST (gimp->fonts));
gimp_container_thaw (gimp->fonts);
/* initialize the document history */
(* status_callback) (NULL, _("Documents"), 0.90);
(* status_callback) (NULL, _("Documents"), 0.80);
gimp_documents_load (gimp);
/* initialize the template list */
(* status_callback) (NULL, _("Templates"), 0.90);
gimp_templates_load (gimp);
(* status_callback) (NULL, NULL, 1.00);
gimp_modules_load (gimp);

View File

@ -128,7 +128,8 @@ struct _Gimp
GimpContainer *documents;
/* image_new values */
GimpImageNewValues image_new_last_values;
GimpContainer *templates;
GimpTemplate *image_new_last_template;
gboolean have_current_cut_buffer;
/* the list of all contexts */

View File

@ -20,94 +20,60 @@
#include <glib-object.h>
#include "libgimpbase/gimpbase.h"
#include "core-types.h"
#include "paint-funcs/paint-funcs.h"
#include "config/gimpcoreconfig.h"
#include "config/gimpconfig.h"
#include "config/gimpconfig-utils.h"
#include "gimp.h"
#include "gimpbuffer.h"
#include "gimpdrawable.h"
#include "gimpimage.h"
#include "gimpimage-new.h"
#include "gimplayer.h"
#include "gimptemplate.h"
#include "gimp-intl.h"
GimpImageNewValues *
gimp_image_new_values_new (Gimp *gimp,
GimpImage *gimage)
GimpTemplate *
gimp_image_new_template_new (Gimp *gimp,
GimpImage *gimage)
{
GimpImageNewValues *values;
GimpTemplate *template;
values = g_new0 (GimpImageNewValues, 1);
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
g_return_val_if_fail (gimage == NULL || GIMP_IS_IMAGE (gimage), NULL);
template = gimp_template_new ("image new values");
if (gimage)
{
values->width = gimp_image_get_width (gimage);
values->height = gimp_image_get_height (gimage);
values->unit = gimp_image_get_unit (gimage);
gimp_image_get_resolution (gimage,
&values->xresolution,
&values->yresolution);
values->type = gimp_image_base_type (gimage);
if (values->type == GIMP_INDEXED)
values->type = GIMP_RGB; /* no indexed images */
values->fill_type = GIMP_BACKGROUND_FILL;
}
gimp_template_set_from_image (template, gimage);
else
{
*values = gimp->image_new_last_values;
}
gimp_config_copy_properties (G_OBJECT (gimp->image_new_last_template),
G_OBJECT (template));
if (gimp->global_buffer && gimp->have_current_cut_buffer)
{
values->width = gimp_buffer_get_width (gimp->global_buffer);
values->height = gimp_buffer_get_height (gimp->global_buffer);
g_object_set (template,
"width", gimp_buffer_get_width (gimp->global_buffer),
"height", gimp_buffer_get_height (gimp->global_buffer),
NULL);
}
return values;
return template;
}
void
gimp_image_new_set_default_values (Gimp *gimp,
GimpImageNewValues *values)
gimp_image_new_set_last_template (Gimp *gimp,
GimpTemplate *template)
{
g_return_if_fail (values != NULL);
gimp->image_new_last_values = *values;
g_return_if_fail (GIMP_IS_GIMP (gimp));
g_return_if_fail (GIMP_IS_TEMPLATE (template));
gimp_config_copy_properties (G_OBJECT (template),
G_OBJECT (gimp->image_new_last_template));
gimp->have_current_cut_buffer = FALSE;
}
void
gimp_image_new_values_free (GimpImageNewValues *values)
{
g_return_if_fail (values != NULL);
g_free (values);
}
gsize
gimp_image_new_calculate_memsize (GimpImageNewValues *values)
{
gint channels;
channels = ((values->type == GIMP_RGB ? 3 : 1) /* color */ +
(values->fill_type == GIMP_TRANSPARENT_FILL) /* alpha */ +
1 /* selection */);
return channels * values->width * values->height;
}
gchar *
gimp_image_new_get_memsize_string (gsize memsize)
{
@ -138,64 +104,13 @@ gimp_image_new_get_memsize_string (gsize memsize)
}
GimpImage *
gimp_image_new_create_image (Gimp *gimp,
GimpImageNewValues *values)
gimp_image_new_create_image (Gimp *gimp,
GimpTemplate *template)
{
GimpImage *gimage;
GimpLayer *layer;
GimpImageType type;
gint width, height;
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
g_return_val_if_fail (GIMP_IS_TEMPLATE (template), NULL);
g_return_val_if_fail (values != NULL, NULL);
gimp_image_new_set_last_template (gimp, template);
gimp_image_new_set_default_values (gimp, values);
switch (values->fill_type)
{
case GIMP_FOREGROUND_FILL:
case GIMP_BACKGROUND_FILL:
case GIMP_WHITE_FILL:
type = (values->type == GIMP_RGB) ? GIMP_RGB_IMAGE : GIMP_GRAY_IMAGE;
break;
case GIMP_TRANSPARENT_FILL:
type = (values->type == GIMP_RGB) ? GIMP_RGBA_IMAGE : GIMP_GRAYA_IMAGE;
break;
default:
type = GIMP_RGB_IMAGE;
break;
}
gimage = gimp_create_image (gimp,
values->width, values->height,
values->type,
TRUE);
gimp_image_set_resolution (gimage, values->xresolution, values->yresolution);
gimp_image_set_unit (gimage, values->unit);
width = gimp_image_get_width (gimage);
height = gimp_image_get_height (gimage);
layer = gimp_layer_new (gimage, width, height,
type, _("Background"),
GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);
if (layer)
{
gimp_image_undo_disable (gimage);
gimp_image_add_layer (gimage, layer, 0);
gimp_image_undo_enable (gimage);
gimp_drawable_fill_by_type (GIMP_DRAWABLE (layer),
gimp_get_current_context (gimp),
values->fill_type);
gimp_image_clean_all (gimage);
gimp_create_display (gimp, gimage, 0x0101);
g_object_unref (gimage);
}
return gimage;
return gimp_template_create_image (gimp, template);
}

View File

@ -20,33 +20,16 @@
#define __GIMP_IMAGE_NEW_H__
struct _GimpImageNewValues
{
gint width;
gint height;
GimpUnit unit;
GimpTemplate * gimp_image_new_template_new (Gimp *gimp,
GimpImage *gimage);
gdouble xresolution;
gdouble yresolution;
GimpUnit res_unit;
GimpImageBaseType type;
GimpFillType fill_type;
};
void gimp_image_new_set_last_template (Gimp *gimp,
GimpTemplate *template);
gchar * gimp_image_new_get_memsize_string (gsize memsize);
GimpImageNewValues * gimp_image_new_values_new (Gimp *gimp,
GimpImage *gimage);
void gimp_image_new_set_default_values (Gimp *gimp,
GimpImageNewValues *values);
void gimp_image_new_values_free (GimpImageNewValues *values);
gsize gimp_image_new_calculate_memsize (GimpImageNewValues *values);
gchar * gimp_image_new_get_memsize_string (gsize memsize);
GimpImage * gimp_image_new_create_image (Gimp *gimp,
GimpImageNewValues *values);
GimpImage * gimp_image_new_create_image (Gimp *gimp,
GimpTemplate *template);
#endif /* __GIMP_IMAGE_NEW__ */

438
app/core/gimptemplate.c Normal file
View File

@ -0,0 +1,438 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* gimptemplate.c
* Copyright (C) 2003 Michael Natterer <mitch@gimp.org>
*
* 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 <glib-object.h>
#include "libgimpbase/gimpbase.h"
#include "core-types.h"
#include "config/gimpconfig.h"
#include "config/gimpconfig-deserialize.h"
#include "config/gimpconfig-serialize.h"
#include "config/gimpconfig-params.h"
#include "config/gimpcoreconfig.h"
#include "gimp.h"
#include "gimpimage.h"
#include "gimplayer.h"
#include "gimptemplate.h"
#include "gimp-intl.h"
enum
{
PROP_0,
PROP_WIDTH,
PROP_HEIGHT,
PROP_UNIT,
PROP_XRESOLUTION,
PROP_YRESOLUTION,
PROP_RESOLUTION_UNIT,
PROP_IMAGE_TYPE,
PROP_FILL_TYPE
};
static void gimp_template_class_init (GimpTemplateClass *klass);
static void gimp_template_init (GimpTemplate *template);
static void gimp_template_config_iface_init (GimpConfigInterface *config_iface);
static void gimp_template_finalize (GObject *object);
static void gimp_template_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_template_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static gboolean gimp_template_serialize (GObject *object,
GimpConfigWriter *writer,
gpointer data);
static gboolean gimp_template_deserialize (GObject *object,
GScanner *scanner,
gint nest_level,
gpointer data);
static GimpViewableClass *parent_class = NULL;
GType
gimp_template_get_type (void)
{
static GType template_type = 0;
if (! template_type)
{
static const GTypeInfo template_info =
{
sizeof (GimpTemplateClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gimp_template_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpTemplate),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_template_init,
};
static const GInterfaceInfo config_iface_info =
{
(GInterfaceInitFunc) gimp_template_config_iface_init,
NULL, /* iface_finalize */
NULL /* iface_data */
};
template_type = g_type_register_static (GIMP_TYPE_VIEWABLE,
"GimpTemplate",
&template_info, 0);
g_type_add_interface_static (template_type,
GIMP_TYPE_CONFIG_INTERFACE,
&config_iface_info);
}
return template_type;
}
static void
gimp_template_class_init (GimpTemplateClass *klass)
{
GObjectClass *object_class;
GimpViewableClass *viewable_class;
object_class = G_OBJECT_CLASS (klass);
viewable_class = GIMP_VIEWABLE_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = gimp_template_finalize;
object_class->set_property = gimp_template_set_property;
object_class->get_property = gimp_template_get_property;
viewable_class->default_stock_id = "gimp-template";
GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_WIDTH, "width",
NULL,
1, GIMP_MAX_IMAGE_SIZE, 256,
0);
GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_HEIGHT, "height",
NULL,
1, GIMP_MAX_IMAGE_SIZE, 256,
0);
GIMP_CONFIG_INSTALL_PROP_UNIT (object_class, PROP_UNIT, "unit",
NULL,
FALSE, GIMP_UNIT_INCH,
0);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_XRESOLUTION,
"xresolution",
NULL,
GIMP_MIN_RESOLUTION, GIMP_MAX_RESOLUTION,
72.0,
0);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_YRESOLUTION,
"yresolution",
NULL,
GIMP_MIN_RESOLUTION, GIMP_MAX_RESOLUTION,
72.0,
0);
GIMP_CONFIG_INSTALL_PROP_UNIT (object_class, PROP_RESOLUTION_UNIT,
"resolution-unit",
NULL,
FALSE, GIMP_UNIT_INCH,
0);
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_IMAGE_TYPE,
"image-type",
NULL,
GIMP_TYPE_IMAGE_BASE_TYPE, GIMP_RGB,
0);
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_FILL_TYPE,
"fill-type",
NULL,
GIMP_TYPE_FILL_TYPE, GIMP_BACKGROUND_FILL,
0);
}
static void
gimp_template_init (GimpTemplate *template)
{
}
static void
gimp_template_config_iface_init (GimpConfigInterface *config_iface)
{
config_iface->serialize = gimp_template_serialize;
config_iface->deserialize = gimp_template_deserialize;
}
static void
gimp_template_finalize (GObject *object)
{
GimpTemplate *template;
template = GIMP_TEMPLATE (object);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_template_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpTemplate *template;
template = GIMP_TEMPLATE (object);
switch (property_id)
{
case PROP_WIDTH:
template->width = g_value_get_int (value);
break;
case PROP_HEIGHT:
template->height = g_value_get_int (value);
break;
case PROP_UNIT:
template->unit = g_value_get_int (value);
break;
case PROP_XRESOLUTION:
template->xresolution = g_value_get_double (value);
break;
case PROP_YRESOLUTION:
template->yresolution = g_value_get_double (value);
break;
case PROP_RESOLUTION_UNIT:
template->resolution_unit = g_value_get_int (value);
break;
case PROP_IMAGE_TYPE:
template->image_type = g_value_get_enum (value);
break;
case PROP_FILL_TYPE:
template->fill_type = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_template_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpTemplate *template;
template = GIMP_TEMPLATE (object);
switch (property_id)
{
case PROP_WIDTH:
g_value_set_int (value, template->width);
break;
case PROP_HEIGHT:
g_value_set_int (value, template->height);
break;
case PROP_UNIT:
g_value_set_int (value, template->unit);
break;
case PROP_XRESOLUTION:
g_value_set_double (value, template->xresolution);
break;
case PROP_YRESOLUTION:
g_value_set_double (value, template->yresolution);
break;
case PROP_RESOLUTION_UNIT:
g_value_set_int (value, template->resolution_unit);
break;
case PROP_IMAGE_TYPE:
g_value_set_enum (value, template->image_type);
break;
case PROP_FILL_TYPE:
g_value_set_enum (value, template->fill_type);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static gboolean
gimp_template_serialize (GObject *object,
GimpConfigWriter *writer,
gpointer data)
{
return gimp_config_serialize_properties (object, writer);
}
static gboolean
gimp_template_deserialize (GObject *object,
GScanner *scanner,
gint nest_level,
gpointer data)
{
return gimp_config_deserialize_properties (object, scanner, nest_level, FALSE);
}
/* public functions */
GimpTemplate *
gimp_template_new (const gchar *name)
{
g_return_val_if_fail (name != NULL, NULL);
return g_object_new (GIMP_TYPE_TEMPLATE,
"name", name,
NULL);
}
void
gimp_template_set_from_config (GimpTemplate *template,
GimpCoreConfig *config)
{
g_return_if_fail (GIMP_IS_TEMPLATE (template));
g_return_if_fail (GIMP_IS_CORE_CONFIG (config));
g_object_set (template,
"width", config->default_image_width,
"height", config->default_image_height,
"unit", config->default_unit,
"xresolution", config->default_xresolution,
"yresolution", config->default_yresolution,
"resolution-unit", config->default_resolution_unit,
"image-type", config->default_image_type,
NULL);
}
void
gimp_template_set_from_image (GimpTemplate *template,
GimpImage *gimage)
{
gdouble xresolution;
gdouble yresolution;
GimpImageBaseType image_type;
g_return_if_fail (GIMP_IS_TEMPLATE (template));
g_return_if_fail (GIMP_IS_IMAGE (gimage));
gimp_image_get_resolution (gimage, &xresolution, &yresolution);
image_type = gimp_image_base_type (gimage);
if (image_type == GIMP_INDEXED)
image_type = GIMP_RGB;
g_object_set (template,
"width", gimp_image_get_width (gimage),
"height", gimp_image_get_height (gimage),
"unit", gimp_image_get_unit (gimage),
"xresolution", xresolution,
"yresolution", yresolution,
"image-type", image_type,
NULL);
}
gsize
gimp_template_calc_memsize (GimpTemplate *template)
{
gint channels;
g_return_val_if_fail (GIMP_IS_TEMPLATE (template), 0);
channels = ((template->image_type == GIMP_RGB ? 3 : 1) /* color */ +
(template->fill_type == GIMP_TRANSPARENT_FILL) /* alpha */ +
1 /* selection */);
return channels * template->width * template->height;
}
GimpImage *
gimp_template_create_image (Gimp *gimp,
GimpTemplate *template)
{
GimpImage *gimage;
GimpLayer *layer;
GimpImageType type;
gint width, height;
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
g_return_val_if_fail (GIMP_IS_TEMPLATE (template), NULL);
switch (template->fill_type)
{
case GIMP_FOREGROUND_FILL:
case GIMP_BACKGROUND_FILL:
case GIMP_WHITE_FILL:
type = (template->image_type == GIMP_RGB) ? GIMP_RGB_IMAGE : GIMP_GRAY_IMAGE;
break;
case GIMP_TRANSPARENT_FILL:
type = (template->image_type == GIMP_RGB) ? GIMP_RGBA_IMAGE : GIMP_GRAYA_IMAGE;
break;
default:
type = GIMP_RGB_IMAGE;
break;
}
gimage = gimp_create_image (gimp,
template->width, template->height,
template->image_type,
TRUE);
gimp_image_undo_disable (gimage);
gimp_image_set_resolution (gimage,
template->xresolution, template->yresolution);
gimp_image_set_unit (gimage, template->unit);
width = gimp_image_get_width (gimage);
height = gimp_image_get_height (gimage);
layer = gimp_layer_new (gimage, width, height,
type, _("Background"),
GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);
gimp_image_add_layer (gimage, layer, 0);
gimp_drawable_fill_by_type (GIMP_DRAWABLE (layer),
gimp_get_current_context (gimp),
template->fill_type);
gimp_image_undo_enable (gimage);
gimp_image_clean_all (gimage);
gimp_create_display (gimp, gimage, 0x0101);
g_object_unref (gimage);
return gimage;
}

76
app/core/gimptemplate.h Normal file
View File

@ -0,0 +1,76 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995-1999 Spencer Kimball and Peter Mattis
*
* gimptemplate.h
* Copyright (C) 2003 Michael Natterer <mitch@gimp.org>
*
* 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.
*/
#ifndef __GIMP_TEMPLATE_H__
#define __GIMP_TEMPLATE_H__
#include "gimpviewable.h"
#define GIMP_TYPE_TEMPLATE (gimp_template_get_type ())
#define GIMP_TEMPLATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_TEMPLATE, GimpTemplate))
#define GIMP_TEMPLATE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_TEMPLATE, GimpTemplateClass))
#define GIMP_IS_TEMPLATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_TEMPLATE))
#define GIMP_IS_TEMPLATE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_TEMPLATE))
#define GIMP_TEMPLATE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_TEMPLATE, GimpTemplateClass))
typedef struct _GimpTemplateClass GimpTemplateClass;
struct _GimpTemplate
{
GimpViewable parent_instance;
gint width;
gint height;
GimpUnit unit;
gdouble xresolution;
gdouble yresolution;
GimpUnit resolution_unit;
GimpImageBaseType image_type;
GimpFillType fill_type;
};
struct _GimpTemplateClass
{
GimpViewableClass parent_instance;
};
GType gimp_template_get_type (void) G_GNUC_CONST;
GimpTemplate * gimp_template_new (const gchar *name);
void gimp_template_set_from_config (GimpTemplate *template,
GimpCoreConfig *config);
void gimp_template_set_from_image (GimpTemplate *template,
GimpImage *gimage);
gsize gimp_template_calc_memsize (GimpTemplate *values);
GimpImage * gimp_template_create_image (Gimp *gimp,
GimpTemplate *template);
#endif /* __GIMP_TEMPLATE__ */

View File

@ -18,6 +18,8 @@
#include "config.h"
#include <string.h>
#include <gtk/gtk.h>
#include "libgimpmath/gimpmath.h"
@ -26,13 +28,16 @@
#include "gui-types.h"
#include "config/gimpconfig-utils.h"
#include "config/gimpguiconfig.h"
#include "core/gimp.h"
#include "core/gimpimage.h"
#include "core/gimpimage-new.h"
#include "core/gimptemplate.h"
#include "widgets/gimpenummenu.h"
#include "widgets/gimpcontainermenuimpl.h"
#include "widgets/gimppropwidgets.h"
#include "widgets/gimpviewabledialog.h"
#include "file-new-dialog.h"
@ -45,43 +50,41 @@
typedef struct
{
GtkWidget *dialog;
GtkWidget *dialog;
GtkWidget *confirm_dialog;
GtkWidget *confirm_dialog;
GtkWidget *option_menu;
GtkWidget *container_menu;
GtkWidget *size_se;
GtkWidget *memsize_label;
GtkWidget *resolution_se;
GtkWidget *couple_resolutions;
GtkWidget *size_se;
GtkWidget *memsize_label;
GtkWidget *resolution_se;
GtkWidget *couple_resolutions;
GtkWidget *type_w;
GtkWidget *fill_type_w;
GimpTemplate *template;
gdouble size;
GimpImageNewValues *values;
gdouble size;
Gimp *gimp;
Gimp *gimp;
} NewImageInfo;
/* local function prototypes */
static void file_new_confirm_dialog (NewImageInfo *info);
static void file_new_confirm_dialog (NewImageInfo *info);
static void file_new_ok_callback (GtkWidget *widget,
gpointer data);
static void file_new_reset_callback (GtkWidget *widget,
gpointer data);
static void file_new_cancel_callback (GtkWidget *widget,
gpointer data);
static void file_new_resolution_callback (GtkWidget *widget,
gpointer data);
static void file_new_image_type_callback (GtkWidget *widget,
gpointer data);
static void file_new_fill_type_callback (GtkWidget *widget,
gpointer data);
static void file_new_image_size_callback (GtkWidget *widget,
gpointer data);
static void file_new_ok_callback (GtkWidget *widget,
NewImageInfo *info);
static void file_new_cancel_callback (GtkWidget *widget,
NewImageInfo *info);
static void file_new_reset_callback (GtkWidget *widget,
NewImageInfo *info);
static void file_new_template_notify (GimpTemplate *template,
GParamSpec *param_spec,
NewImageInfo *info);
static void file_new_template_select (GimpContainerMenu *menu,
GimpViewable *object,
gpointer insert_data,
NewImageInfo *info);
/* public functions */
@ -104,12 +107,16 @@ file_new_dialog_create (Gimp *gimp,
GtkWidget *spinbutton2;
g_return_if_fail (GIMP_IS_GIMP (gimp));
g_return_if_fail (! gimage || GIMP_IS_IMAGE (gimage));
g_return_if_fail (gimage == NULL || GIMP_IS_IMAGE (gimage));
info = g_new0 (NewImageInfo, 1);
info->gimp = gimp;
info->values = gimp_image_new_values_new (gimp, gimage);
info->gimp = gimp;
info->template = gimp_image_new_template_new (gimp, gimage);
g_signal_connect (info->template, "notify",
G_CALLBACK (file_new_template_notify),
info);
info->dialog =
gimp_viewable_dialog_new (NULL,
@ -139,6 +146,32 @@ file_new_dialog_create (Gimp *gimp,
main_vbox, TRUE, TRUE, 0);
gtk_widget_show (main_vbox);
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
label = gtk_label_new_with_mnemonic (_("From _Template:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
info->option_menu = gtk_option_menu_new ();
gtk_box_pack_start (GTK_BOX (hbox), info->option_menu, TRUE, TRUE, 0);
gtk_widget_show (info->option_menu);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), info->option_menu);
info->container_menu = gimp_container_menu_new (gimp->templates, NULL, 16);
gtk_option_menu_set_menu (GTK_OPTION_MENU (info->option_menu),
info->container_menu);
gtk_widget_show (info->container_menu);
gimp_container_menu_select_item (GIMP_CONTAINER_MENU (info->container_menu),
NULL);
g_signal_connect (info->container_menu, "select_item",
G_CALLBACK (file_new_template_select),
info);
/* Image size frame */
frame = gtk_frame_new (_("Image Size"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
@ -194,7 +227,7 @@ file_new_dialog_create (Gimp *gimp,
gtk_table_attach_defaults (GTK_TABLE (table), abox, 1, 2, 3, 5);
gtk_widget_show (abox);
info->size_se = gimp_size_entry_new (0, info->values->unit, "%a",
info->size_se = gimp_size_entry_new (0, info->template->unit, "%a",
FALSE, FALSE, TRUE, SB_WIDTH,
GIMP_SIZE_ENTRY_UPDATE_SIZE);
gtk_table_set_col_spacing (GTK_TABLE (info->size_se), 1, 4);
@ -268,32 +301,11 @@ file_new_dialog_create (Gimp *gimp,
GTK_SPIN_BUTTON (spinbutton2));
/* initialize the sizeentry */
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (info->size_se), 0,
info->values->xresolution, FALSE);
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (info->size_se), 1,
info->values->yresolution, FALSE);
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (info->size_se), 0,
GIMP_MIN_IMAGE_SIZE,
GIMP_MAX_IMAGE_SIZE);
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (info->size_se), 1,
GIMP_MIN_IMAGE_SIZE,
GIMP_MAX_IMAGE_SIZE);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (info->size_se), 0,
info->values->width);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (info->size_se), 1,
info->values->height);
g_signal_connect (info->size_se, "refval_changed",
G_CALLBACK (file_new_image_size_callback),
info);
g_signal_connect (info->size_se, "value_changed",
G_CALLBACK (file_new_image_size_callback),
info);
/* initialize the size label */
file_new_image_size_callback (info->size_se, info);
gimp_prop_size_entry_connect (G_OBJECT (info->template),
"width", "height", "unit",
info->size_se, NULL,
info->template->xresolution,
info->template->yresolution);
/* the resolution labels */
label = gtk_label_new (_("Resolution X:"));
@ -318,11 +330,10 @@ file_new_dialog_create (Gimp *gimp,
1, 2);
gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), SB_WIDTH);
info->resolution_se =
gimp_size_entry_new (1, gimp->config->default_resolution_unit,
_("pixels/%a"),
FALSE, FALSE, FALSE, SB_WIDTH,
GIMP_SIZE_ENTRY_UPDATE_RESOLUTION);
info->resolution_se = gimp_size_entry_new (1, info->template->resolution_unit,
_("pixels/%a"),
FALSE, FALSE, FALSE, SB_WIDTH,
GIMP_SIZE_ENTRY_UPDATE_RESOLUTION);
gtk_table_set_col_spacing (GTK_TABLE (info->resolution_se), 1, 2);
gtk_table_set_col_spacing (GTK_TABLE (info->resolution_se), 2, 2);
gtk_table_set_row_spacing (GTK_TABLE (info->resolution_se), 0, 2);
@ -333,66 +344,40 @@ file_new_dialog_create (Gimp *gimp,
1, 2, 0, 1);
gtk_widget_show (spinbutton);
gtk_container_add (GTK_CONTAINER (abox), info->resolution_se);
gtk_container_add (GTK_CONTAINER (abox), info->resolution_se);
gtk_widget_show (info->resolution_se);
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (info->resolution_se),
0, GIMP_MIN_RESOLUTION,
GIMP_MAX_RESOLUTION);
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (info->resolution_se),
1, GIMP_MIN_RESOLUTION,
GIMP_MAX_RESOLUTION);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (info->resolution_se), 0,
info->values->xresolution);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (info->resolution_se), 1,
info->values->yresolution);
g_signal_connect (info->resolution_se, "value_changed",
G_CALLBACK (file_new_resolution_callback),
info);
/* the resolution chainbutton */
info->couple_resolutions = gimp_chain_button_new (GIMP_CHAIN_RIGHT);
gimp_chain_button_set_active
(GIMP_CHAIN_BUTTON (info->couple_resolutions),
ABS (info->values->xresolution - info->values->yresolution)
< GIMP_MIN_RESOLUTION);
gtk_table_attach_defaults (GTK_TABLE (info->resolution_se),
info->couple_resolutions, 2, 3, 0, 2);
gtk_widget_show (info->couple_resolutions);
gimp_prop_size_entry_connect (G_OBJECT (info->template),
"xresolution", "yresolution",
"resolution-unit",
info->resolution_se,
info->couple_resolutions,
1.0, 1.0);
/* hbox containing the Image type and fill type frames */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
/* frame for Image Type */
frame = gimp_enum_radio_frame_new_with_range (GIMP_TYPE_IMAGE_BASE_TYPE,
GIMP_RGB, GIMP_GRAY,
gtk_label_new (_("Image Type")),
2,
G_CALLBACK (file_new_image_type_callback),
info,
&info->type_w);
gimp_radio_group_set_active (GTK_RADIO_BUTTON (info->type_w),
GINT_TO_POINTER (info->values->type));
frame = gimp_prop_enum_radio_frame_new (G_OBJECT (info->template),
"image-type",
_("Image Type"),
GIMP_RGB, GIMP_GRAY);
gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
gtk_widget_show (frame);
/* frame for Fill Type */
frame = gimp_enum_radio_frame_new_with_range (GIMP_TYPE_FILL_TYPE,
GIMP_FOREGROUND_FILL,
GIMP_TRANSPARENT_FILL,
gtk_label_new (_("Fill Type")),
2,
G_CALLBACK (file_new_fill_type_callback),
info,
&info->fill_type_w);
gimp_radio_group_set_active (GTK_RADIO_BUTTON (info->fill_type_w),
GINT_TO_POINTER (info->values->fill_type));
frame = gimp_prop_enum_radio_frame_new (G_OBJECT (info->template),
"fill-type",
_("Fill Type"),
-1, -1);
gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
gtk_widget_show (frame);
@ -405,33 +390,9 @@ file_new_dialog_create (Gimp *gimp,
/* private functions */
static void
file_new_ok_callback (GtkWidget *widget,
gpointer data)
file_new_ok_callback (GtkWidget *widget,
NewImageInfo *info)
{
NewImageInfo *info;
GimpImageNewValues *values;
info = (NewImageInfo*) data;
values = info->values;
/* get the image size in pixels */
values->width =
RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (info->size_se), 0));
values->height =
RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (info->size_se), 1));
/* get the resolution in dpi */
values->xresolution =
gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (info->resolution_se), 0);
values->yresolution =
gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (info->resolution_se), 1);
/* get the units */
values->unit =
gimp_size_entry_get_unit (GIMP_SIZE_ENTRY (info->size_se));
values->res_unit =
gimp_size_entry_get_unit (GIMP_SIZE_ENTRY (info->resolution_se));
if (info->size > GIMP_GUI_CONFIG (info->gimp->config)->max_new_image_size)
{
file_new_confirm_dialog (info);
@ -439,72 +400,41 @@ file_new_ok_callback (GtkWidget *widget,
else
{
gtk_widget_destroy (info->dialog);
gimp_image_new_create_image (info->gimp, values);
gimp_image_new_values_free (values);
gimp_image_new_create_image (info->gimp, info->template);
g_object_unref (info->template);
g_free (info);
}
}
static void
file_new_reset_callback (GtkWidget *widget,
gpointer data)
file_new_cancel_callback (GtkWidget *widget,
NewImageInfo *info)
{
NewImageInfo *info;
GimpCoreConfig *config;
info = (NewImageInfo *) data;
config = info->gimp->config;
g_signal_handlers_block_by_func (info->resolution_se,
file_new_resolution_callback,
info);
gimp_chain_button_set_active
(GIMP_CHAIN_BUTTON (info->couple_resolutions),
ABS (config->default_xresolution -
config->default_yresolution) < GIMP_MIN_RESOLUTION);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (info->resolution_se), 0,
config->default_xresolution);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (info->resolution_se), 1,
config->default_yresolution);
gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (info->resolution_se),
config->default_resolution_unit);
g_signal_handlers_unblock_by_func (info->resolution_se,
file_new_resolution_callback,
info);
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (info->size_se), 0,
config->default_xresolution, TRUE);
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (info->size_se), 1,
config->default_yresolution, TRUE);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (info->size_se), 0,
config->default_image_width);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (info->size_se), 1,
config->default_image_height);
gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (info->size_se),
config->default_unit);
gimp_radio_group_set_active (GTK_RADIO_BUTTON (info->type_w),
GINT_TO_POINTER (config->default_image_type));
gimp_radio_group_set_active (GTK_RADIO_BUTTON (info->fill_type_w),
GINT_TO_POINTER (GIMP_BACKGROUND_FILL));
gtk_widget_destroy (info->dialog);
g_object_unref (info->template);
g_free (info);
}
static void
file_new_cancel_callback (GtkWidget *widget,
gpointer data)
file_new_reset_callback (GtkWidget *widget,
NewImageInfo *info)
{
NewImageInfo *info;
gint width;
gint height;
info = (NewImageInfo*) data;
width = info->gimp->config->default_image_width;
height = info->gimp->config->default_image_height;
gtk_widget_destroy (info->dialog);
gimp_image_new_values_free (info->values);
g_free (info);
gimp_template_set_from_config (info->template, info->gimp->config);
g_object_set (info->template,
"width", width,
"height", height,
"fill-type", GIMP_BACKGROUND_FILL,
NULL);
gimp_container_menu_select_item (GIMP_CONTAINER_MENU (info->container_menu),
NULL);
}
/* local callback of file_new_confirm_dialog() */
@ -513,17 +443,15 @@ file_new_confirm_dialog_callback (GtkWidget *widget,
gboolean create,
gpointer data)
{
NewImageInfo *info;
info = (NewImageInfo*) data;
NewImageInfo *info = (NewImageInfo*) data;
info->confirm_dialog = NULL;
if (create)
{
gtk_widget_destroy (info->dialog);
gimp_image_new_create_image (info->gimp, info->values);
gimp_image_new_values_free (info->values);
gimp_image_new_create_image (info->gimp, info->template);
g_object_unref (info->template);
g_free (info);
}
else
@ -542,8 +470,6 @@ file_new_confirm_dialog (NewImageInfo *info)
size = gimp_image_new_get_memsize_string (info->size);
max_size = gimp_image_new_get_memsize_string (GIMP_GUI_CONFIG (info->gimp->config)->max_new_image_size);
/* xgettext:no-c-format */
text = g_strdup_printf (_("You are trying to create an image with\n"
"an initial size of %s.\n\n"
"Choose OK to create this image anyway.\n"
@ -579,103 +505,50 @@ file_new_confirm_dialog (NewImageInfo *info)
}
static void
file_new_resolution_callback (GtkWidget *widget,
gpointer data)
file_new_template_notify (GimpTemplate *template,
GParamSpec *param_spec,
NewImageInfo *info)
{
NewImageInfo *info;
gchar *text;
static gdouble xres = 0.0;
static gdouble yres = 0.0;
gdouble new_xres;
gdouble new_yres;
info = (NewImageInfo *) data;
new_xres = gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (widget), 0);
new_yres = gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (widget), 1);
if (gimp_chain_button_get_active
(GIMP_CHAIN_BUTTON (info->couple_resolutions)))
if (! strcmp (param_spec->name, "xresolution"))
{
g_signal_handlers_block_by_func (info->resolution_se,
file_new_resolution_callback,
info);
if (new_xres != xres)
{
yres = new_yres = xres = new_xres;
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (widget), 1, yres);
}
if (new_yres != yres)
{
xres = new_xres = yres = new_yres;
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (widget), 0, xres);
}
g_signal_handlers_unblock_by_func (info->resolution_se,
file_new_resolution_callback,
info);
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (info->size_se), 0,
template->xresolution, FALSE);
}
else
else if (! strcmp (param_spec->name, "yresolution"))
{
if (new_xres != xres)
xres = new_xres;
if (new_yres != yres)
yres = new_yres;
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (info->size_se), 1,
template->yresolution, FALSE);
}
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (info->size_se), 0,
xres, FALSE);
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (info->size_se), 1,
yres, FALSE);
file_new_image_size_callback (widget, data);
}
static void
file_new_image_type_callback (GtkWidget *widget,
gpointer data)
{
NewImageInfo *info;
info = (NewImageInfo*) data;
gimp_radio_button_update (widget, &info->values->type);
file_new_image_size_callback (widget, data);
}
static void
file_new_fill_type_callback (GtkWidget *widget,
gpointer data)
{
NewImageInfo *info;
info = (NewImageInfo*) data;
gimp_radio_button_update (widget, &info->values->fill_type);
file_new_image_size_callback (widget, data);
}
static void
file_new_image_size_callback (GtkWidget *widget,
gpointer data)
{
NewImageInfo *info;
gchar *text;
info = (NewImageInfo*) data;
info->values->width =
RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (info->size_se), 0));
info->values->height =
RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (info->size_se), 1));
info->size = gimp_image_new_calculate_memsize (info->values);
info->size = gimp_template_calc_memsize (info->template);
text = gimp_image_new_get_memsize_string (info->size);
gtk_label_set_text (GTK_LABEL (info->memsize_label), text);
g_free (text);
}
static void
file_new_template_select (GimpContainerMenu *menu,
GimpViewable *object,
gpointer insert_data,
NewImageInfo *info)
{
if (object)
{
gint width;
gint height;
width = GIMP_TEMPLATE (object)->width;
height = GIMP_TEMPLATE (object)->height;
gimp_config_copy_properties (G_OBJECT (object),
G_OBJECT (info->template));
g_object_set (info->template,
"width", width,
"height", height,
NULL);
}
}

View File

@ -18,6 +18,8 @@
#include "config.h"
#include <string.h>
#include <gtk/gtk.h>
#include "libgimpwidgets/gimpwidgets.h"
@ -31,7 +33,7 @@
#include "core/gimpcontext.h"
#include "core/gimpimage.h"
#include "core/gimpimage-undo.h"
#include "core/gimpobject.h"
#include "core/gimptemplate.h"
#include "file/file-open.h"
#include "file/file-save.h"
@ -77,6 +79,9 @@
/* local function prototypes */
static void file_new_template_callback (GtkWidget *widget,
gchar *name,
gpointer data);
static void file_revert_confirm_callback (GtkWidget *widget,
gboolean revert,
gpointer data);
@ -264,6 +269,25 @@ file_save_a_copy_cmd_callback (GtkWidget *widget,
file_save_a_copy_dialog_show (gdisp->gimage, global_menu_factory);
}
void
file_save_template_cmd_callback (GtkWidget *widget,
gpointer data,
guint action)
{
GimpDisplay *gdisp;
GtkWidget *qbox;
return_if_no_display (gdisp, data);
qbox = gimp_query_string_box (_("Create New Template"),
gimp_standard_help_func,
"dialogs/new_template.html",
_("Enter a name for this template"),
NULL,
G_OBJECT (gdisp->gimage), "disconnect",
file_new_template_callback, gdisp->gimage);
gtk_widget_show (qbox);
}
void
file_revert_cmd_callback (GtkWidget *widget,
gpointer data,
@ -354,8 +378,30 @@ file_file_open_dialog (Gimp *gimp,
file_open_dialog_show (gimp, NULL, uri, global_menu_factory);
}
/* private functions */
static void
file_new_template_callback (GtkWidget *widget,
gchar *name,
gpointer data)
{
GimpTemplate *template;
GimpImage *gimage;
gimage = (GimpImage *) data;
if (! (name && strlen (name)))
name = _("(Unnamed Template)");
template = gimp_template_new (name);
gimp_template_set_from_image (template, gimage);
gimp_container_add (gimage->gimp->templates,
GIMP_OBJECT (template));
g_object_unref (template);
}
static void
file_revert_confirm_callback (GtkWidget *widget,
gboolean revert,

View File

@ -52,6 +52,9 @@ void file_save_as_cmd_callback (GtkWidget *widget,
void file_save_a_copy_cmd_callback (GtkWidget *widget,
gpointer data,
guint action);
void file_save_template_cmd_callback (GtkWidget *widget,
gpointer data,
guint action);
void file_revert_cmd_callback (GtkWidget *widget,
gpointer data,

View File

@ -18,6 +18,8 @@
#include "config.h"
#include <string.h>
#include <gtk/gtk.h>
#include "libgimpmath/gimpmath.h"
@ -26,13 +28,16 @@
#include "gui-types.h"
#include "config/gimpconfig-utils.h"
#include "config/gimpguiconfig.h"
#include "core/gimp.h"
#include "core/gimpimage.h"
#include "core/gimpimage-new.h"
#include "core/gimptemplate.h"
#include "widgets/gimpenummenu.h"
#include "widgets/gimpcontainermenuimpl.h"
#include "widgets/gimppropwidgets.h"
#include "widgets/gimpviewabledialog.h"
#include "file-new-dialog.h"
@ -45,43 +50,41 @@
typedef struct
{
GtkWidget *dialog;
GtkWidget *dialog;
GtkWidget *confirm_dialog;
GtkWidget *confirm_dialog;
GtkWidget *option_menu;
GtkWidget *container_menu;
GtkWidget *size_se;
GtkWidget *memsize_label;
GtkWidget *resolution_se;
GtkWidget *couple_resolutions;
GtkWidget *size_se;
GtkWidget *memsize_label;
GtkWidget *resolution_se;
GtkWidget *couple_resolutions;
GtkWidget *type_w;
GtkWidget *fill_type_w;
GimpTemplate *template;
gdouble size;
GimpImageNewValues *values;
gdouble size;
Gimp *gimp;
Gimp *gimp;
} NewImageInfo;
/* local function prototypes */
static void file_new_confirm_dialog (NewImageInfo *info);
static void file_new_confirm_dialog (NewImageInfo *info);
static void file_new_ok_callback (GtkWidget *widget,
gpointer data);
static void file_new_reset_callback (GtkWidget *widget,
gpointer data);
static void file_new_cancel_callback (GtkWidget *widget,
gpointer data);
static void file_new_resolution_callback (GtkWidget *widget,
gpointer data);
static void file_new_image_type_callback (GtkWidget *widget,
gpointer data);
static void file_new_fill_type_callback (GtkWidget *widget,
gpointer data);
static void file_new_image_size_callback (GtkWidget *widget,
gpointer data);
static void file_new_ok_callback (GtkWidget *widget,
NewImageInfo *info);
static void file_new_cancel_callback (GtkWidget *widget,
NewImageInfo *info);
static void file_new_reset_callback (GtkWidget *widget,
NewImageInfo *info);
static void file_new_template_notify (GimpTemplate *template,
GParamSpec *param_spec,
NewImageInfo *info);
static void file_new_template_select (GimpContainerMenu *menu,
GimpViewable *object,
gpointer insert_data,
NewImageInfo *info);
/* public functions */
@ -104,12 +107,16 @@ file_new_dialog_create (Gimp *gimp,
GtkWidget *spinbutton2;
g_return_if_fail (GIMP_IS_GIMP (gimp));
g_return_if_fail (! gimage || GIMP_IS_IMAGE (gimage));
g_return_if_fail (gimage == NULL || GIMP_IS_IMAGE (gimage));
info = g_new0 (NewImageInfo, 1);
info->gimp = gimp;
info->values = gimp_image_new_values_new (gimp, gimage);
info->gimp = gimp;
info->template = gimp_image_new_template_new (gimp, gimage);
g_signal_connect (info->template, "notify",
G_CALLBACK (file_new_template_notify),
info);
info->dialog =
gimp_viewable_dialog_new (NULL,
@ -139,6 +146,32 @@ file_new_dialog_create (Gimp *gimp,
main_vbox, TRUE, TRUE, 0);
gtk_widget_show (main_vbox);
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
label = gtk_label_new_with_mnemonic (_("From _Template:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
info->option_menu = gtk_option_menu_new ();
gtk_box_pack_start (GTK_BOX (hbox), info->option_menu, TRUE, TRUE, 0);
gtk_widget_show (info->option_menu);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), info->option_menu);
info->container_menu = gimp_container_menu_new (gimp->templates, NULL, 16);
gtk_option_menu_set_menu (GTK_OPTION_MENU (info->option_menu),
info->container_menu);
gtk_widget_show (info->container_menu);
gimp_container_menu_select_item (GIMP_CONTAINER_MENU (info->container_menu),
NULL);
g_signal_connect (info->container_menu, "select_item",
G_CALLBACK (file_new_template_select),
info);
/* Image size frame */
frame = gtk_frame_new (_("Image Size"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
@ -194,7 +227,7 @@ file_new_dialog_create (Gimp *gimp,
gtk_table_attach_defaults (GTK_TABLE (table), abox, 1, 2, 3, 5);
gtk_widget_show (abox);
info->size_se = gimp_size_entry_new (0, info->values->unit, "%a",
info->size_se = gimp_size_entry_new (0, info->template->unit, "%a",
FALSE, FALSE, TRUE, SB_WIDTH,
GIMP_SIZE_ENTRY_UPDATE_SIZE);
gtk_table_set_col_spacing (GTK_TABLE (info->size_se), 1, 4);
@ -268,32 +301,11 @@ file_new_dialog_create (Gimp *gimp,
GTK_SPIN_BUTTON (spinbutton2));
/* initialize the sizeentry */
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (info->size_se), 0,
info->values->xresolution, FALSE);
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (info->size_se), 1,
info->values->yresolution, FALSE);
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (info->size_se), 0,
GIMP_MIN_IMAGE_SIZE,
GIMP_MAX_IMAGE_SIZE);
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (info->size_se), 1,
GIMP_MIN_IMAGE_SIZE,
GIMP_MAX_IMAGE_SIZE);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (info->size_se), 0,
info->values->width);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (info->size_se), 1,
info->values->height);
g_signal_connect (info->size_se, "refval_changed",
G_CALLBACK (file_new_image_size_callback),
info);
g_signal_connect (info->size_se, "value_changed",
G_CALLBACK (file_new_image_size_callback),
info);
/* initialize the size label */
file_new_image_size_callback (info->size_se, info);
gimp_prop_size_entry_connect (G_OBJECT (info->template),
"width", "height", "unit",
info->size_se, NULL,
info->template->xresolution,
info->template->yresolution);
/* the resolution labels */
label = gtk_label_new (_("Resolution X:"));
@ -318,11 +330,10 @@ file_new_dialog_create (Gimp *gimp,
1, 2);
gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), SB_WIDTH);
info->resolution_se =
gimp_size_entry_new (1, gimp->config->default_resolution_unit,
_("pixels/%a"),
FALSE, FALSE, FALSE, SB_WIDTH,
GIMP_SIZE_ENTRY_UPDATE_RESOLUTION);
info->resolution_se = gimp_size_entry_new (1, info->template->resolution_unit,
_("pixels/%a"),
FALSE, FALSE, FALSE, SB_WIDTH,
GIMP_SIZE_ENTRY_UPDATE_RESOLUTION);
gtk_table_set_col_spacing (GTK_TABLE (info->resolution_se), 1, 2);
gtk_table_set_col_spacing (GTK_TABLE (info->resolution_se), 2, 2);
gtk_table_set_row_spacing (GTK_TABLE (info->resolution_se), 0, 2);
@ -333,66 +344,40 @@ file_new_dialog_create (Gimp *gimp,
1, 2, 0, 1);
gtk_widget_show (spinbutton);
gtk_container_add (GTK_CONTAINER (abox), info->resolution_se);
gtk_container_add (GTK_CONTAINER (abox), info->resolution_se);
gtk_widget_show (info->resolution_se);
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (info->resolution_se),
0, GIMP_MIN_RESOLUTION,
GIMP_MAX_RESOLUTION);
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (info->resolution_se),
1, GIMP_MIN_RESOLUTION,
GIMP_MAX_RESOLUTION);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (info->resolution_se), 0,
info->values->xresolution);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (info->resolution_se), 1,
info->values->yresolution);
g_signal_connect (info->resolution_se, "value_changed",
G_CALLBACK (file_new_resolution_callback),
info);
/* the resolution chainbutton */
info->couple_resolutions = gimp_chain_button_new (GIMP_CHAIN_RIGHT);
gimp_chain_button_set_active
(GIMP_CHAIN_BUTTON (info->couple_resolutions),
ABS (info->values->xresolution - info->values->yresolution)
< GIMP_MIN_RESOLUTION);
gtk_table_attach_defaults (GTK_TABLE (info->resolution_se),
info->couple_resolutions, 2, 3, 0, 2);
gtk_widget_show (info->couple_resolutions);
gimp_prop_size_entry_connect (G_OBJECT (info->template),
"xresolution", "yresolution",
"resolution-unit",
info->resolution_se,
info->couple_resolutions,
1.0, 1.0);
/* hbox containing the Image type and fill type frames */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
/* frame for Image Type */
frame = gimp_enum_radio_frame_new_with_range (GIMP_TYPE_IMAGE_BASE_TYPE,
GIMP_RGB, GIMP_GRAY,
gtk_label_new (_("Image Type")),
2,
G_CALLBACK (file_new_image_type_callback),
info,
&info->type_w);
gimp_radio_group_set_active (GTK_RADIO_BUTTON (info->type_w),
GINT_TO_POINTER (info->values->type));
frame = gimp_prop_enum_radio_frame_new (G_OBJECT (info->template),
"image-type",
_("Image Type"),
GIMP_RGB, GIMP_GRAY);
gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
gtk_widget_show (frame);
/* frame for Fill Type */
frame = gimp_enum_radio_frame_new_with_range (GIMP_TYPE_FILL_TYPE,
GIMP_FOREGROUND_FILL,
GIMP_TRANSPARENT_FILL,
gtk_label_new (_("Fill Type")),
2,
G_CALLBACK (file_new_fill_type_callback),
info,
&info->fill_type_w);
gimp_radio_group_set_active (GTK_RADIO_BUTTON (info->fill_type_w),
GINT_TO_POINTER (info->values->fill_type));
frame = gimp_prop_enum_radio_frame_new (G_OBJECT (info->template),
"fill-type",
_("Fill Type"),
-1, -1);
gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
gtk_widget_show (frame);
@ -405,33 +390,9 @@ file_new_dialog_create (Gimp *gimp,
/* private functions */
static void
file_new_ok_callback (GtkWidget *widget,
gpointer data)
file_new_ok_callback (GtkWidget *widget,
NewImageInfo *info)
{
NewImageInfo *info;
GimpImageNewValues *values;
info = (NewImageInfo*) data;
values = info->values;
/* get the image size in pixels */
values->width =
RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (info->size_se), 0));
values->height =
RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (info->size_se), 1));
/* get the resolution in dpi */
values->xresolution =
gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (info->resolution_se), 0);
values->yresolution =
gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (info->resolution_se), 1);
/* get the units */
values->unit =
gimp_size_entry_get_unit (GIMP_SIZE_ENTRY (info->size_se));
values->res_unit =
gimp_size_entry_get_unit (GIMP_SIZE_ENTRY (info->resolution_se));
if (info->size > GIMP_GUI_CONFIG (info->gimp->config)->max_new_image_size)
{
file_new_confirm_dialog (info);
@ -439,72 +400,41 @@ file_new_ok_callback (GtkWidget *widget,
else
{
gtk_widget_destroy (info->dialog);
gimp_image_new_create_image (info->gimp, values);
gimp_image_new_values_free (values);
gimp_image_new_create_image (info->gimp, info->template);
g_object_unref (info->template);
g_free (info);
}
}
static void
file_new_reset_callback (GtkWidget *widget,
gpointer data)
file_new_cancel_callback (GtkWidget *widget,
NewImageInfo *info)
{
NewImageInfo *info;
GimpCoreConfig *config;
info = (NewImageInfo *) data;
config = info->gimp->config;
g_signal_handlers_block_by_func (info->resolution_se,
file_new_resolution_callback,
info);
gimp_chain_button_set_active
(GIMP_CHAIN_BUTTON (info->couple_resolutions),
ABS (config->default_xresolution -
config->default_yresolution) < GIMP_MIN_RESOLUTION);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (info->resolution_se), 0,
config->default_xresolution);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (info->resolution_se), 1,
config->default_yresolution);
gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (info->resolution_se),
config->default_resolution_unit);
g_signal_handlers_unblock_by_func (info->resolution_se,
file_new_resolution_callback,
info);
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (info->size_se), 0,
config->default_xresolution, TRUE);
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (info->size_se), 1,
config->default_yresolution, TRUE);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (info->size_se), 0,
config->default_image_width);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (info->size_se), 1,
config->default_image_height);
gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (info->size_se),
config->default_unit);
gimp_radio_group_set_active (GTK_RADIO_BUTTON (info->type_w),
GINT_TO_POINTER (config->default_image_type));
gimp_radio_group_set_active (GTK_RADIO_BUTTON (info->fill_type_w),
GINT_TO_POINTER (GIMP_BACKGROUND_FILL));
gtk_widget_destroy (info->dialog);
g_object_unref (info->template);
g_free (info);
}
static void
file_new_cancel_callback (GtkWidget *widget,
gpointer data)
file_new_reset_callback (GtkWidget *widget,
NewImageInfo *info)
{
NewImageInfo *info;
gint width;
gint height;
info = (NewImageInfo*) data;
width = info->gimp->config->default_image_width;
height = info->gimp->config->default_image_height;
gtk_widget_destroy (info->dialog);
gimp_image_new_values_free (info->values);
g_free (info);
gimp_template_set_from_config (info->template, info->gimp->config);
g_object_set (info->template,
"width", width,
"height", height,
"fill-type", GIMP_BACKGROUND_FILL,
NULL);
gimp_container_menu_select_item (GIMP_CONTAINER_MENU (info->container_menu),
NULL);
}
/* local callback of file_new_confirm_dialog() */
@ -513,17 +443,15 @@ file_new_confirm_dialog_callback (GtkWidget *widget,
gboolean create,
gpointer data)
{
NewImageInfo *info;
info = (NewImageInfo*) data;
NewImageInfo *info = (NewImageInfo*) data;
info->confirm_dialog = NULL;
if (create)
{
gtk_widget_destroy (info->dialog);
gimp_image_new_create_image (info->gimp, info->values);
gimp_image_new_values_free (info->values);
gimp_image_new_create_image (info->gimp, info->template);
g_object_unref (info->template);
g_free (info);
}
else
@ -542,8 +470,6 @@ file_new_confirm_dialog (NewImageInfo *info)
size = gimp_image_new_get_memsize_string (info->size);
max_size = gimp_image_new_get_memsize_string (GIMP_GUI_CONFIG (info->gimp->config)->max_new_image_size);
/* xgettext:no-c-format */
text = g_strdup_printf (_("You are trying to create an image with\n"
"an initial size of %s.\n\n"
"Choose OK to create this image anyway.\n"
@ -579,103 +505,50 @@ file_new_confirm_dialog (NewImageInfo *info)
}
static void
file_new_resolution_callback (GtkWidget *widget,
gpointer data)
file_new_template_notify (GimpTemplate *template,
GParamSpec *param_spec,
NewImageInfo *info)
{
NewImageInfo *info;
gchar *text;
static gdouble xres = 0.0;
static gdouble yres = 0.0;
gdouble new_xres;
gdouble new_yres;
info = (NewImageInfo *) data;
new_xres = gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (widget), 0);
new_yres = gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (widget), 1);
if (gimp_chain_button_get_active
(GIMP_CHAIN_BUTTON (info->couple_resolutions)))
if (! strcmp (param_spec->name, "xresolution"))
{
g_signal_handlers_block_by_func (info->resolution_se,
file_new_resolution_callback,
info);
if (new_xres != xres)
{
yres = new_yres = xres = new_xres;
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (widget), 1, yres);
}
if (new_yres != yres)
{
xres = new_xres = yres = new_yres;
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (widget), 0, xres);
}
g_signal_handlers_unblock_by_func (info->resolution_se,
file_new_resolution_callback,
info);
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (info->size_se), 0,
template->xresolution, FALSE);
}
else
else if (! strcmp (param_spec->name, "yresolution"))
{
if (new_xres != xres)
xres = new_xres;
if (new_yres != yres)
yres = new_yres;
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (info->size_se), 1,
template->yresolution, FALSE);
}
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (info->size_se), 0,
xres, FALSE);
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (info->size_se), 1,
yres, FALSE);
file_new_image_size_callback (widget, data);
}
static void
file_new_image_type_callback (GtkWidget *widget,
gpointer data)
{
NewImageInfo *info;
info = (NewImageInfo*) data;
gimp_radio_button_update (widget, &info->values->type);
file_new_image_size_callback (widget, data);
}
static void
file_new_fill_type_callback (GtkWidget *widget,
gpointer data)
{
NewImageInfo *info;
info = (NewImageInfo*) data;
gimp_radio_button_update (widget, &info->values->fill_type);
file_new_image_size_callback (widget, data);
}
static void
file_new_image_size_callback (GtkWidget *widget,
gpointer data)
{
NewImageInfo *info;
gchar *text;
info = (NewImageInfo*) data;
info->values->width =
RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (info->size_se), 0));
info->values->height =
RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (info->size_se), 1));
info->size = gimp_image_new_calculate_memsize (info->values);
info->size = gimp_template_calc_memsize (info->template);
text = gimp_image_new_get_memsize_string (info->size);
gtk_label_set_text (GTK_LABEL (info->memsize_label), text);
g_free (text);
}
static void
file_new_template_select (GimpContainerMenu *menu,
GimpViewable *object,
gpointer insert_data,
NewImageInfo *info)
{
if (object)
{
gint width;
gint height;
width = GIMP_TEMPLATE (object)->width;
height = GIMP_TEMPLATE (object)->height;
gimp_config_copy_properties (G_OBJECT (object),
G_OBJECT (info->template));
g_object_set (info->template,
"width", width,
"height", height,
NULL);
}
}

View File

@ -112,6 +112,10 @@ GimpItemFactoryEntry image_menu_entries[] =
file_save_a_copy_cmd_callback, 0 },
NULL,
"file/dialogs/file_save.html", NULL },
{ { N_("/File/Save as Template..."), NULL,
file_save_template_cmd_callback, 0 },
NULL,
"file/dialogs/file_save.html", NULL },
{ { N_("/File/Revert..."), NULL,
file_revert_cmd_callback, 0,
"<StockItem>", GTK_STOCK_REVERT_TO_SAVED },

View File

@ -112,6 +112,10 @@ GimpItemFactoryEntry image_menu_entries[] =
file_save_a_copy_cmd_callback, 0 },
NULL,
"file/dialogs/file_save.html", NULL },
{ { N_("/File/Save as Template..."), NULL,
file_save_template_cmd_callback, 0 },
NULL,
"file/dialogs/file_save.html", NULL },
{ { N_("/File/Revert..."), NULL,
file_revert_cmd_callback, 0,
"<StockItem>", GTK_STOCK_REVERT_TO_SAVED },

View File

@ -181,9 +181,6 @@ gimp_container_menu_impl_insert_item (GimpContainerMenu *menu,
gtk_menu_reorder_child (GTK_MENU (menu),
GIMP_CONTAINER_MENU_IMPL (menu)->empty_item, -1);
if (g_list_length (GTK_MENU_SHELL (menu)->children) == 2)
gtk_widget_hide (GIMP_CONTAINER_MENU_IMPL (menu)->empty_item);
return (gpointer) menu_item;
}
@ -248,6 +245,7 @@ gimp_container_menu_impl_select_item (GimpContainerMenu *menu,
gpointer insert_data)
{
GtkWidget *menu_item;
gint index;
if (insert_data)
menu_item = GTK_WIDGET (insert_data);
@ -256,11 +254,19 @@ gimp_container_menu_impl_select_item (GimpContainerMenu *menu,
if (menu_item)
{
gint index;
gtk_widget_hide (GIMP_CONTAINER_MENU_IMPL (menu)->empty_item);
index = gimp_container_get_child_index (menu->container,
GIMP_OBJECT (viewable));
gimp_container_menu_impl_set_history (menu, index);
}
else
{
gtk_widget_show (GIMP_CONTAINER_MENU_IMPL (menu)->empty_item);
index = gimp_container_num_children (menu->container);
gimp_container_menu_impl_set_history (menu, index);
}
}

View File

@ -1644,30 +1644,79 @@ gimp_prop_coordinates_new (GObject *config,
gdouble xresolution,
gdouble yresolution,
gboolean has_chainbutton)
{
GtkWidget *sizeentry;
GtkWidget *chainbutton = NULL;
sizeentry = gimp_size_entry_new (2, GIMP_UNIT_INCH, unit_format,
FALSE, FALSE, TRUE, 10,
update_policy);
if (has_chainbutton)
{
chainbutton = gimp_chain_button_new (GIMP_CHAIN_BOTTOM);
gtk_table_attach_defaults (GTK_TABLE (sizeentry), chainbutton,
1, 3, 3, 4);
gtk_widget_show (chainbutton);
}
if (! gimp_prop_size_entry_connect (config,
x_property_name,
y_property_name,
unit_property_name,
sizeentry,
chainbutton,
xresolution,
yresolution))
{
gtk_widget_destroy (sizeentry);
return NULL;
}
return sizeentry;
}
gboolean
gimp_prop_size_entry_connect (GObject *config,
const gchar *x_property_name,
const gchar *y_property_name,
const gchar *unit_property_name,
GtkWidget *sizeentry,
GtkWidget *chainbutton,
gdouble xresolution,
gdouble yresolution)
{
GParamSpec *x_param_spec;
GParamSpec *y_param_spec;
GParamSpec *unit_param_spec;
GtkWidget *sizeentry;
gdouble x_value;
gdouble y_value;
gdouble *old_x_value;
gdouble *old_y_value;
GimpUnit unit_value;
gboolean chain_checked = FALSE;
g_return_val_if_fail (GIMP_IS_SIZE_ENTRY (sizeentry), FALSE);
g_return_val_if_fail (GIMP_SIZE_ENTRY (sizeentry)->number_of_fields == 2,
FALSE);
g_return_val_if_fail (chainbutton == NULL ||
GIMP_IS_CHAIN_BUTTON (chainbutton), FALSE);
x_param_spec = find_param_spec (config, x_property_name, G_STRLOC);
if (! x_param_spec)
return NULL;
return FALSE;
y_param_spec = find_param_spec (config, y_property_name, G_STRLOC);
if (! y_param_spec)
return NULL;
return FALSE;
if (unit_property_name)
{
unit_param_spec = check_param_spec (config, unit_property_name,
GIMP_TYPE_PARAM_UNIT, G_STRLOC);
if (! unit_param_spec)
return NULL;
return FALSE;
g_object_get (config,
unit_property_name, &unit_value,
@ -1707,14 +1756,10 @@ gimp_prop_coordinates_new (GObject *config,
" both int or both double",
G_STRLOC, x_property_name, y_property_name,
g_type_name (G_TYPE_FROM_INSTANCE (config)));
return NULL;
return FALSE;
}
sizeentry = gimp_size_entry_new (2, unit_value, unit_format,
FALSE, FALSE, TRUE, 10,
update_policy);
switch (update_policy)
switch (GIMP_SIZE_ENTRY (sizeentry)->update_policy)
{
case GIMP_SIZE_ENTRY_UPDATE_SIZE:
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (sizeentry), 0,
@ -1760,19 +1805,24 @@ gimp_prop_coordinates_new (GObject *config,
g_object_set_data (G_OBJECT (sizeentry), "gimp-config-param-spec-unit",
unit_param_spec);
if (has_chainbutton)
old_x_value = g_new0 (gdouble, 1);
*old_x_value = x_value;
g_object_set_data_full (G_OBJECT (sizeentry), "old-x-value",
old_x_value,
(GDestroyNotify) g_free);
old_y_value = g_new0 (gdouble, 1);
*old_y_value = y_value;
g_object_set_data_full (G_OBJECT (sizeentry), "old-y-value",
old_y_value,
(GDestroyNotify) g_free);
if (chainbutton)
{
GtkWidget *button;
button = gimp_chain_button_new (GIMP_CHAIN_BOTTOM);
if (chain_checked)
gimp_chain_button_set_active (GIMP_CHAIN_BUTTON (button), TRUE);
gimp_chain_button_set_active (GIMP_CHAIN_BUTTON (chainbutton), TRUE);
gtk_table_attach_defaults (GTK_TABLE (sizeentry), button, 1, 3, 3, 4);
gtk_widget_show (button);
g_object_set_data (G_OBJECT (sizeentry), "chainbutton", button);
g_object_set_data (G_OBJECT (sizeentry), "chainbutton", chainbutton);
}
g_signal_connect (sizeentry, "value_changed",
@ -1803,7 +1853,7 @@ gimp_prop_coordinates_new (GObject *config,
sizeentry);
}
return sizeentry;
return TRUE;
}
static void
@ -1834,26 +1884,10 @@ gimp_prop_coordinates_callback (GimpSizeEntry *sizeentry,
unit_value = gimp_size_entry_get_unit (sizeentry);
old_x_value = g_object_get_data (G_OBJECT (sizeentry), "old-x-value");
if (! old_x_value)
{
old_x_value = g_new0 (gdouble, 1);
*old_x_value = 0.0;
g_object_set_data_full (G_OBJECT (sizeentry), "old-x-value",
old_x_value,
(GDestroyNotify) g_free);
}
old_y_value = g_object_get_data (G_OBJECT (sizeentry), "old-y-value");
if (! old_y_value)
{
old_y_value = g_new0 (gdouble, 1);
*old_y_value = 0.0;
g_object_set_data_full (G_OBJECT (sizeentry), "old-y-value",
old_y_value,
(GDestroyNotify) g_free);
}
if (! old_x_value || ! old_y_value)
return;
if (x_value != y_value)
{
@ -1865,20 +1899,9 @@ gimp_prop_coordinates_callback (GimpSizeEntry *sizeentry,
gimp_chain_button_get_active (GIMP_CHAIN_BUTTON (chainbutton)))
{
if (x_value != *old_x_value)
{
*old_x_value = x_value;
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (sizeentry), 1,
x_value);
return;
}
if (y_value != *old_y_value)
{
*old_y_value = y_value;
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (sizeentry), 0,
y_value);
return;
}
y_value = x_value;
else if (y_value != *old_y_value)
x_value = y_value;
}
}
@ -1892,8 +1915,8 @@ gimp_prop_coordinates_callback (GimpSizeEntry *sizeentry,
G_IS_PARAM_SPEC_INT (y_param_spec))
{
g_object_set (config,
x_param_spec->name, (gint) x_value,
y_param_spec->name, (gint) y_value,
x_param_spec->name, ROUND (x_value),
y_param_spec->name, ROUND (y_value),
unit_param_spec ?
unit_param_spec->name : NULL, unit_value,
@ -1904,8 +1927,8 @@ gimp_prop_coordinates_callback (GimpSizeEntry *sizeentry,
G_IS_PARAM_SPEC_DOUBLE (y_param_spec))
{
g_object_set (config,
x_param_spec->name, x_value,
y_param_spec->name, y_value,
x_param_spec->name, x_value,
y_param_spec->name, y_value,
unit_param_spec ?
unit_param_spec->name : NULL, unit_value,

View File

@ -140,6 +140,15 @@ GtkWidget * gimp_prop_coordinates_new (GObject *config,
gdouble yresolution,
gboolean has_chainbutton);
gboolean gimp_prop_size_entry_connect (GObject *config,
const gchar *x_property_name,
const gchar *y_property_name,
const gchar *unit_property_name,
GtkWidget *sizeentry,
GtkWidget *chainbutton,
gdouble xresolution,
gdouble yresolution);
/* GimpParamColor */

View File

@ -1644,30 +1644,79 @@ gimp_prop_coordinates_new (GObject *config,
gdouble xresolution,
gdouble yresolution,
gboolean has_chainbutton)
{
GtkWidget *sizeentry;
GtkWidget *chainbutton = NULL;
sizeentry = gimp_size_entry_new (2, GIMP_UNIT_INCH, unit_format,
FALSE, FALSE, TRUE, 10,
update_policy);
if (has_chainbutton)
{
chainbutton = gimp_chain_button_new (GIMP_CHAIN_BOTTOM);
gtk_table_attach_defaults (GTK_TABLE (sizeentry), chainbutton,
1, 3, 3, 4);
gtk_widget_show (chainbutton);
}
if (! gimp_prop_size_entry_connect (config,
x_property_name,
y_property_name,
unit_property_name,
sizeentry,
chainbutton,
xresolution,
yresolution))
{
gtk_widget_destroy (sizeentry);
return NULL;
}
return sizeentry;
}
gboolean
gimp_prop_size_entry_connect (GObject *config,
const gchar *x_property_name,
const gchar *y_property_name,
const gchar *unit_property_name,
GtkWidget *sizeentry,
GtkWidget *chainbutton,
gdouble xresolution,
gdouble yresolution)
{
GParamSpec *x_param_spec;
GParamSpec *y_param_spec;
GParamSpec *unit_param_spec;
GtkWidget *sizeentry;
gdouble x_value;
gdouble y_value;
gdouble *old_x_value;
gdouble *old_y_value;
GimpUnit unit_value;
gboolean chain_checked = FALSE;
g_return_val_if_fail (GIMP_IS_SIZE_ENTRY (sizeentry), FALSE);
g_return_val_if_fail (GIMP_SIZE_ENTRY (sizeentry)->number_of_fields == 2,
FALSE);
g_return_val_if_fail (chainbutton == NULL ||
GIMP_IS_CHAIN_BUTTON (chainbutton), FALSE);
x_param_spec = find_param_spec (config, x_property_name, G_STRLOC);
if (! x_param_spec)
return NULL;
return FALSE;
y_param_spec = find_param_spec (config, y_property_name, G_STRLOC);
if (! y_param_spec)
return NULL;
return FALSE;
if (unit_property_name)
{
unit_param_spec = check_param_spec (config, unit_property_name,
GIMP_TYPE_PARAM_UNIT, G_STRLOC);
if (! unit_param_spec)
return NULL;
return FALSE;
g_object_get (config,
unit_property_name, &unit_value,
@ -1707,14 +1756,10 @@ gimp_prop_coordinates_new (GObject *config,
" both int or both double",
G_STRLOC, x_property_name, y_property_name,
g_type_name (G_TYPE_FROM_INSTANCE (config)));
return NULL;
return FALSE;
}
sizeentry = gimp_size_entry_new (2, unit_value, unit_format,
FALSE, FALSE, TRUE, 10,
update_policy);
switch (update_policy)
switch (GIMP_SIZE_ENTRY (sizeentry)->update_policy)
{
case GIMP_SIZE_ENTRY_UPDATE_SIZE:
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (sizeentry), 0,
@ -1760,19 +1805,24 @@ gimp_prop_coordinates_new (GObject *config,
g_object_set_data (G_OBJECT (sizeentry), "gimp-config-param-spec-unit",
unit_param_spec);
if (has_chainbutton)
old_x_value = g_new0 (gdouble, 1);
*old_x_value = x_value;
g_object_set_data_full (G_OBJECT (sizeentry), "old-x-value",
old_x_value,
(GDestroyNotify) g_free);
old_y_value = g_new0 (gdouble, 1);
*old_y_value = y_value;
g_object_set_data_full (G_OBJECT (sizeentry), "old-y-value",
old_y_value,
(GDestroyNotify) g_free);
if (chainbutton)
{
GtkWidget *button;
button = gimp_chain_button_new (GIMP_CHAIN_BOTTOM);
if (chain_checked)
gimp_chain_button_set_active (GIMP_CHAIN_BUTTON (button), TRUE);
gimp_chain_button_set_active (GIMP_CHAIN_BUTTON (chainbutton), TRUE);
gtk_table_attach_defaults (GTK_TABLE (sizeentry), button, 1, 3, 3, 4);
gtk_widget_show (button);
g_object_set_data (G_OBJECT (sizeentry), "chainbutton", button);
g_object_set_data (G_OBJECT (sizeentry), "chainbutton", chainbutton);
}
g_signal_connect (sizeentry, "value_changed",
@ -1803,7 +1853,7 @@ gimp_prop_coordinates_new (GObject *config,
sizeentry);
}
return sizeentry;
return TRUE;
}
static void
@ -1834,26 +1884,10 @@ gimp_prop_coordinates_callback (GimpSizeEntry *sizeentry,
unit_value = gimp_size_entry_get_unit (sizeentry);
old_x_value = g_object_get_data (G_OBJECT (sizeentry), "old-x-value");
if (! old_x_value)
{
old_x_value = g_new0 (gdouble, 1);
*old_x_value = 0.0;
g_object_set_data_full (G_OBJECT (sizeentry), "old-x-value",
old_x_value,
(GDestroyNotify) g_free);
}
old_y_value = g_object_get_data (G_OBJECT (sizeentry), "old-y-value");
if (! old_y_value)
{
old_y_value = g_new0 (gdouble, 1);
*old_y_value = 0.0;
g_object_set_data_full (G_OBJECT (sizeentry), "old-y-value",
old_y_value,
(GDestroyNotify) g_free);
}
if (! old_x_value || ! old_y_value)
return;
if (x_value != y_value)
{
@ -1865,20 +1899,9 @@ gimp_prop_coordinates_callback (GimpSizeEntry *sizeentry,
gimp_chain_button_get_active (GIMP_CHAIN_BUTTON (chainbutton)))
{
if (x_value != *old_x_value)
{
*old_x_value = x_value;
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (sizeentry), 1,
x_value);
return;
}
if (y_value != *old_y_value)
{
*old_y_value = y_value;
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (sizeentry), 0,
y_value);
return;
}
y_value = x_value;
else if (y_value != *old_y_value)
x_value = y_value;
}
}
@ -1892,8 +1915,8 @@ gimp_prop_coordinates_callback (GimpSizeEntry *sizeentry,
G_IS_PARAM_SPEC_INT (y_param_spec))
{
g_object_set (config,
x_param_spec->name, (gint) x_value,
y_param_spec->name, (gint) y_value,
x_param_spec->name, ROUND (x_value),
y_param_spec->name, ROUND (y_value),
unit_param_spec ?
unit_param_spec->name : NULL, unit_value,
@ -1904,8 +1927,8 @@ gimp_prop_coordinates_callback (GimpSizeEntry *sizeentry,
G_IS_PARAM_SPEC_DOUBLE (y_param_spec))
{
g_object_set (config,
x_param_spec->name, x_value,
y_param_spec->name, y_value,
x_param_spec->name, x_value,
y_param_spec->name, y_value,
unit_param_spec ?
unit_param_spec->name : NULL, unit_value,

View File

@ -140,6 +140,15 @@ GtkWidget * gimp_prop_coordinates_new (GObject *config,
gdouble yresolution,
gboolean has_chainbutton);
gboolean gimp_prop_size_entry_connect (GObject *config,
const gchar *x_property_name,
const gchar *y_property_name,
const gchar *unit_property_name,
GtkWidget *sizeentry,
GtkWidget *chainbutton,
gdouble xresolution,
gdouble yresolution);
/* GimpParamColor */