Gimp/libgimp/gimpgradientmenu.c
Sven Neumann 5d1fac2a7c match the parameter name in the header to please gtk-doc.
2002-12-18  Sven Neumann  <sven@gimp.org>

	* libgimp/gimpgradientmenu.c (gimp_gradient_select_widget): match
	the parameter name in the header to please gtk-doc.

2002-12-18  Sven Neumann  <sven@gimp.org>

	* libgimp/libgimp-sections.txt: removed the functions Nathan added
	since the Makefile explicitely excludes them and they shouldn't
	show up in the docs until the API has settled and they are moved
	out of gimpmisc.h.

	* libgimp/tmpl/gimpmisc.sgml: regenerated.
2002-12-18 13:56:48 +00:00

321 lines
8.6 KiB
C

/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimpgradientmenu.c
* Copyright (C) 1998 Andy Thomas
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; 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>
#ifdef __GNUC__
#warning GTK_DISABLE_DEPRECATED
#endif
#undef GTK_DISABLE_DEPRECATED
#include "gimp.h"
#include "gimpui.h"
/* Idea is to have a function to call that returns a widget that
* completely controls the selection of a gradient.
* you get a widget returned that you can use in a table say.
* In:- Initial gradient name. Null means use current selection.
* pointer to func to call when gradient changes (GimpRunGradientCallback).
* Returned:- Pointer to a widget that you can use in UI.
*
* Widget simply made up of a preview widget (20x40) containing the gradient
* which can be clicked on to changed the gradient selection.
*/
#define GSEL_DATA_KEY "__gsel_data"
#define CELL_SIZE_HEIGHT 18
#define CELL_SIZE_WIDTH 84
struct __gradients_sel
{
gchar *dname;
GimpRunGradientCallback cback;
GtkWidget *gradient_preview;
GtkWidget *button;
gchar *gradient_popup_pnt;
gint width;
gchar *gradient_name; /* Local copy */
gdouble *grad_data; /* local copy */
gint sample_size;
gpointer data;
};
typedef struct __gradients_sel GSelect;
static void
gradient_pre_update (GtkWidget *gradient_preview,
gint width_data,
gdouble *grad_data)
{
gint x;
gint y;
gdouble *src;
gdouble r, g, b, a;
gdouble c0, c1;
guchar *p0;
guchar *p1;
guchar *even;
guchar *odd;
gint width;
width = width_data / 4;
/* Draw the gradient */
src = grad_data;
p0 = even = g_malloc (width * 3);
p1 = odd = g_malloc (width * 3);
for (x = 0; x < width; x++)
{
r = src[x*4+0];
g = src[x*4+1];
b = src[x*4+2];
a = src[x*4+3];
if ((x / GIMP_CHECK_SIZE_SM) & 1)
{
c0 = GIMP_CHECK_LIGHT;
c1 = GIMP_CHECK_DARK;
}
else
{
c0 = GIMP_CHECK_DARK;
c1 = GIMP_CHECK_LIGHT;
}
*p0++ = (c0 + (r - c0) * a) * 255.0;
*p0++ = (c0 + (g - c0) * a) * 255.0;
*p0++ = (c0 + (b - c0) * a) * 255.0;
*p1++ = (c1 + (r - c1) * a) * 255.0;
*p1++ = (c1 + (g - c1) * a) * 255.0;
*p1++ = (c1 + (b - c1) * a) * 255.0;
}
for (y = 0; y < CELL_SIZE_HEIGHT; y++)
{
if ((y / GIMP_CHECK_SIZE_SM) & 1)
gtk_preview_draw_row (GTK_PREVIEW (gradient_preview),
(guchar *)odd, 0, y,
(width < CELL_SIZE_WIDTH) ? width : CELL_SIZE_WIDTH);
else
gtk_preview_draw_row (GTK_PREVIEW (gradient_preview),
(guchar *)even, 0, y,
(width < CELL_SIZE_WIDTH) ? width : CELL_SIZE_WIDTH);
}
g_free (even);
g_free (odd);
gtk_widget_queue_draw (gradient_preview);
}
static void
gradient_select_invoker (gchar *name,
gint width,
gdouble *grad_data,
gint closing,
gpointer data)
{
GSelect *gsel = (GSelect*)data;
if (gsel->grad_data != NULL)
g_free (gsel->grad_data);
gsel->width = width;
if (gsel->gradient_name)
g_free (gsel->gradient_name);
gsel->gradient_name = g_strdup (name);
/* one row only each row has four doubles r,g,b,a */
gsel->grad_data = g_new (gdouble, width);
/* printf("name = %s width = %d\n",name,width);*/
g_memmove (gsel->grad_data, grad_data, width * sizeof (gdouble));
gradient_pre_update (gsel->gradient_preview, gsel->width, gsel->grad_data);
if (gsel->cback != NULL)
(gsel->cback)(name, width, grad_data, closing, gsel->data);
if (closing)
gtk_widget_set_sensitive (gsel->button, TRUE);
}
static void
gradient_preview_callback (GtkWidget *widget,
gpointer data)
{
GSelect *gsel = (GSelect*)data;
gtk_widget_set_sensitive (gsel->button, FALSE);
gsel->gradient_popup_pnt =
gimp_interactive_selection_gradient ((gsel->dname) ? gsel->dname
: "Gradient Plugin Selection",
gsel->gradient_name,
gsel->sample_size,
gradient_select_invoker,
gsel);
}
/**
* gimp_gradient_select_widget:
* @gname: Title of the dialog to use. NULL means to use the default title.
* @igradient: Initial gradient name. NULL means to use current selection.
* @cback: a function to call when the selected gradient changes.
* @data: a pointer to arbitary data to be used in the call to @cback.
*
* Creates a new #GtkWidget that completely controls the selection of a
* gradient. This widget is suitable for placement in a table in a
* plug-in dialog.
*
* Returns:A #GtkWidget that you can use in your UI.
*/
GtkWidget *
gimp_gradient_select_widget (gchar *gname,
gchar *igradient,
GimpRunGradientCallback cback,
gpointer data)
{
GtkWidget *button;
GtkWidget *hbox;
GtkWidget *gradient;
gint width;
gdouble *grad_data;
gchar *gradient_name;
GSelect *gsel;
gsel = g_new (GSelect, 1);
hbox = gtk_hbox_new (FALSE, 3);
gtk_widget_show(hbox);
button = gtk_button_new ();
gradient = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (gradient),
CELL_SIZE_WIDTH, CELL_SIZE_HEIGHT);
gtk_widget_show (gradient);
gtk_container_add (GTK_CONTAINER (button), gradient);
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (gradient_preview_callback),
gsel);
gtk_widget_show(button);
gsel->button = button;
gsel->cback = cback;
gsel->data = data;
gsel->grad_data = NULL;
gsel->gradient_preview = gradient;
gsel->dname = gname;
gsel->gradient_popup_pnt = NULL;
gsel->sample_size = CELL_SIZE_WIDTH;
/* Do initial gradient setup */
gradient_name =
gimp_gradients_get_gradient_data (igradient,
CELL_SIZE_WIDTH, &width,
&grad_data);
if (gradient_name)
{
gradient_pre_update (gsel->gradient_preview, width, grad_data);
gsel->grad_data = grad_data;
gsel->gradient_name = gradient_name;
gsel->width = width;
}
else
{
gsel->gradient_name = g_strdup (igradient);
}
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
g_object_set_data (G_OBJECT (hbox), GSEL_DATA_KEY, gsel);
return hbox;
}
/**
* gimp_gradient_select_widget_close_popup:
* @widget: A gradient select widget.
*
* Closes the popup window associated with @widget.
*/
void
gimp_gradient_select_widget_close_popup (GtkWidget *widget)
{
GSelect *gsel;
gsel = (GSelect*) g_object_get_data (G_OBJECT (widget), GSEL_DATA_KEY);
if (gsel && gsel->gradient_popup_pnt)
{
gimp_gradients_close_popup (gsel->gradient_popup_pnt);
gsel->gradient_popup_pnt = NULL;
}
}
/**
* gimp_gradient_select_widget_set_popup:
* @widget: A gradient select widget.
* @gname: gradient name to set.
*
* Sets the current gradient for the gradient
* select widget. Calls the callback function if one was
* supplied in the call to gimp_gradient_select_widget().
*/
void
gimp_gradient_select_widget_set_popup (GtkWidget *widget,
gchar *gname)
{
gint width;
gdouble *grad_data;
gchar *gradient_name;
GSelect *gsel;
gsel = (GSelect*) g_object_get_data (G_OBJECT (widget), GSEL_DATA_KEY);
if (gsel)
{
gradient_name =
gimp_gradients_get_gradient_data (gname,
gsel->sample_size, &width,
&grad_data);
if (gradient_name)
{
gradient_select_invoker (gname, width, grad_data, 0, gsel);
if (gsel->gradient_popup_pnt)
gimp_gradients_set_popup (gsel->gradient_popup_pnt, gname);
}
}
}