libgimp/gimpuitypes.h abstract class for resource selection buttons.

2006-06-25  Manish Singh  <yosh@gimp.org>

        * libgimp/gimpuitypes.h
        * libgimp/gimpselectbutton.[ch]: abstract class for resource selection
        buttons.

        * libgimp/gimpfontselectbutton.[ch]: derive from GimpSelectButton.

        * libgimp/gimpbrushselectbutton.[ch]
        * libgimp/gimpgradientselectbutton.[ch]
        * libgimp/gimppaletteselectbutton.[ch]
        * libgimp/gimppatternselectbutton.[ch]: replacements for
        gimp_foo_select widgets, akin to GimpFontSelectButton.

        * libgimp/gimpbrushmenu.[ch]
        * libgimp/gimpgradientmenu.[ch]
        * libgimp/gimppalettemenu.[ch]
        * libgimp/gimppatternmenu.[ch]: deprecate old API, and reimplement
        in terms of GimpFooSelectButton.

        * libgimp/gimpfontmenu.[ch]: change to use the GimpSelectButton API.

        * libgimp/gimpuimarshal.list: new marshallers for the above new
        widgets.

        * libgimp/gimpui.h: add new headers.

        * libgimp/Makefile.am: add new files.

        * plug-ins/FractalExplorer/Dialogs.c
        * plug-ins/gfig/gfig-dialog.c
        * plug-ins/gfig/gfig-style.[ch]
        * plug-ins/script-fu/script-fu-interface.c: use new API.
This commit is contained in:
Manish Singh 2006-06-26 01:47:22 +00:00 committed by Manish Singh
parent b39f3ce1c3
commit 68dfb3f223
31 changed files with 3884 additions and 1900 deletions

View File

@ -1,3 +1,37 @@
2006-06-25 Manish Singh <yosh@gimp.org>
* libgimp/gimpuitypes.h
* libgimp/gimpselectbutton.[ch]: abstract class for resource selection
buttons.
* libgimp/gimpfontselectbutton.[ch]: derive from GimpSelectButton.
* libgimp/gimpbrushselectbutton.[ch]
* libgimp/gimpgradientselectbutton.[ch]
* libgimp/gimppaletteselectbutton.[ch]
* libgimp/gimppatternselectbutton.[ch]: replacements for
gimp_foo_select widgets, akin to GimpFontSelectButton.
* libgimp/gimpbrushmenu.[ch]
* libgimp/gimpgradientmenu.[ch]
* libgimp/gimppalettemenu.[ch]
* libgimp/gimppatternmenu.[ch]: deprecate old API, and reimplement
in terms of GimpFooSelectButton.
* libgimp/gimpfontmenu.[ch]: change to use the GimpSelectButton API.
* libgimp/gimpuimarshal.list: new marshallers for the above new
widgets.
* libgimp/gimpui.h: add new headers.
* libgimp/Makefile.am: add new files.
* plug-ins/FractalExplorer/Dialogs.c
* plug-ins/gfig/gfig-dialog.c
* plug-ins/gfig/gfig-style.[ch]
* plug-ins/script-fu/script-fu-interface.c: use new API.
2006-06-25 Manish Singh <yosh@gimp.org>
* libgimp/gimpbrushes.c

View File

@ -234,42 +234,52 @@ libgimp_2_0_la_SOURCES = \
$(libgimp_2_0_la_sources)
libgimpui_2_0_la_sources = \
gimpui.c \
gimpui.h \
gimpuitypes.h \
gimpaspectpreview.c \
gimpaspectpreview.h \
gimpbrushmenu.c \
gimpbrushmenu.h \
gimpdrawablecombobox.c \
gimpdrawablecombobox.h \
gimpdrawablepreview.c \
gimpdrawablepreview.h \
gimpexport.c \
gimpexport.h \
gimpfontmenu.c \
gimpfontmenu.h \
gimpfontselectbutton.c \
gimpfontselectbutton.h \
gimpgradientmenu.c \
gimpgradientmenu.h \
gimpimagecombobox.c \
gimpimagecombobox.h \
gimpmenu.c \
gimpmenu.h \
gimppalettemenu.c \
gimppalettemenu.h \
gimppatternmenu.c \
gimppatternmenu.h \
gimppixbuf.c \
gimppixbuf.h \
gimpprocbrowserdialog.c \
gimpprocbrowserdialog.h \
gimpprocview.c \
gimpprocview.h \
gimpprogressbar.c \
gimpprogressbar.h \
gimpzoompreview.c \
gimpui.c \
gimpui.h \
gimpuitypes.h \
gimpaspectpreview.c \
gimpaspectpreview.h \
gimpbrushmenu.c \
gimpbrushmenu.h \
gimpbrushselectbutton.c \
gimpbrushselectbutton.h \
gimpdrawablecombobox.c \
gimpdrawablecombobox.h \
gimpdrawablepreview.c \
gimpdrawablepreview.h \
gimpexport.c \
gimpexport.h \
gimpfontmenu.c \
gimpfontmenu.h \
gimpfontselectbutton.c \
gimpfontselectbutton.h \
gimpgradientmenu.c \
gimpgradientmenu.h \
gimpgradientselectbutton.c \
gimpgradientselectbutton.h \
gimpimagecombobox.c \
gimpimagecombobox.h \
gimpmenu.c \
gimpmenu.h \
gimppalettemenu.c \
gimppalettemenu.h \
gimppaletteselectbutton.c \
gimppaletteselectbutton.h \
gimppatternmenu.c \
gimppatternmenu.h \
gimppatternselectbutton.c \
gimppatternselectbutton.h \
gimppixbuf.c \
gimppixbuf.h \
gimpprocbrowserdialog.c \
gimpprocbrowserdialog.h \
gimpprocview.c \
gimpprocview.h \
gimpprogressbar.c \
gimpprogressbar.h \
gimpselectbutton.c \
gimpselectbutton.h \
gimpzoompreview.c \
gimpzoompreview.h
libgimpui_2_0_la_built_sources = \
@ -283,53 +293,58 @@ libgimpui_2_0_la_SOURCES = \
$(libgimpui_2_0_la_sources)
gimpinclude_HEADERS = \
gimp.h \
gimpcompat.h \
gimptypes.h \
gimpenums.h \
${PDB_WRAPPERS_H} \
gimpbrushes.h \
gimpbrushselect.h \
gimpchannel.h \
gimpdrawable.h \
gimpfontselect.h \
gimpgimprc.h \
gimpgradients.h \
gimpgradientselect.h \
gimpimage.h \
gimplayer.h \
gimppalette.h \
gimppalettes.h \
gimppaletteselect.h \
gimppatterns.h \
gimppatternselect.h \
gimppixelfetcher.h \
gimppixelrgn.h \
gimpplugin.h \
gimpproceduraldb.h \
gimpprogress.h \
gimpregioniterator.h \
gimpselection.h \
gimptile.h \
gimp.h \
gimpcompat.h \
gimptypes.h \
gimpenums.h \
${PDB_WRAPPERS_H} \
gimpbrushes.h \
gimpbrushselect.h \
gimpchannel.h \
gimpdrawable.h \
gimpfontselect.h \
gimpgimprc.h \
gimpgradients.h \
gimpgradientselect.h \
gimpimage.h \
gimplayer.h \
gimppalette.h \
gimppalettes.h \
gimppaletteselect.h \
gimppatterns.h \
gimppatternselect.h \
gimppixelfetcher.h \
gimppixelrgn.h \
gimpplugin.h \
gimpproceduraldb.h \
gimpprogress.h \
gimpregioniterator.h \
gimpselection.h \
gimptile.h \
\
gimpui.h \
gimpuitypes.h \
gimpaspectpreview.h \
gimpbrushmenu.h \
gimpdrawablecombobox.h \
gimpdrawablepreview.h \
gimpexport.h \
gimpfontmenu.h \
gimpfontselectbutton.h \
gimpgradientmenu.h \
gimpimagecombobox.h \
gimpmenu.h \
gimppalettemenu.h \
gimppatternmenu.h \
gimppixbuf.h \
gimpprocbrowserdialog.h \
gimpprocview.h \
gimpprogressbar.h \
gimpui.h \
gimpuitypes.h \
gimpaspectpreview.h \
gimpbrushmenu.h \
gimpbrushselectbutton.h \
gimpdrawablecombobox.h \
gimpdrawablepreview.h \
gimpexport.h \
gimpfontmenu.h \
gimpfontselectbutton.h \
gimpgradientmenu.h \
gimpgradientselectbutton.h \
gimpimagecombobox.h \
gimpmenu.h \
gimppalettemenu.h \
gimppaletteselectbutton.h \
gimppatternmenu.h \
gimppatternselectbutton.h \
gimppixbuf.h \
gimpprocbrowserdialog.h \
gimpprocview.h \
gimpprogressbar.h \
gimpselectbutton.h \
gimpzoompreview.h
libgimp_2_0_la_LDFLAGS = \

View File

@ -22,82 +22,33 @@
#include "config.h"
#include <string.h>
#include "gimp.h"
#include "gimpui.h"
#include "libgimp-intl.h"
#include "gimpuitypes.h"
#include "gimpbrushselectbutton.h"
#undef GIMP_DISABLE_DEPRECATED
#include "gimpbrushmenu.h"
#define BRUSH_SELECT_DATA_KEY "gimp-brush-select-data"
#define CELL_SIZE 20
typedef struct _CompatCallbackData CompatCallbackData;
typedef struct _BrushSelect BrushSelect;
struct _BrushSelect
struct _CompatCallbackData
{
gchar *title;
GimpRunBrushCallback callback;
gpointer data;
GtkWidget *preview;
GtkWidget *button;
GtkWidget *popup;
gchar *brush_name; /* Local copy */
gdouble opacity;
gint spacing;
GimpLayerModeEffects paint_mode;
gint width;
gint height;
guchar *mask_data; /* local copy */
const gchar *temp_brush_callback;
GimpRunBrushCallback callback;
gpointer data;
};
/* local function prototypes */
static void gimp_brush_select_widget_callback (const gchar *name,
gdouble opacity,
gint spacing,
GimpLayerModeEffects paint_mode,
gint width,
gint height,
const guchar *mask_data,
gboolean closing,
gpointer data);
static void gimp_brush_select_widget_clicked (GtkWidget *widget,
BrushSelect *brush_sel);
static void gimp_brush_select_widget_destroy (GtkWidget *widget,
BrushSelect *brush_sel);
static gboolean gimp_brush_select_preview_events (GtkWidget *widget,
GdkEvent *event,
BrushSelect *brush_sel);
static void gimp_brush_select_preview_update (GtkWidget *preview,
gint brush_width,
gint brush_height,
const guchar *mask_data);
static void gimp_brush_select_preview_resize (BrushSelect *brush_sel);
static void gimp_brush_select_popup_open (BrushSelect *brush_sel,
gint x,
gint y);
static void gimp_brush_select_popup_close (BrushSelect *brush_sel);
static void gimp_brush_select_drag_data_received (GtkWidget *preview,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time,
GtkWidget *widget);
static const GtkTargetEntry target = { "application/x-gimp-brush-name", 0 };
static void compat_callback (GimpBrushSelectButton *brush_button,
const gchar *brush_name,
gdouble opacity,
gint spacing,
GimpLayerModeEffects paint_mode,
gint width,
gint height,
const guchar *mask_data,
gboolean dialog_closing,
gpointer data);
/**
@ -125,107 +76,23 @@ gimp_brush_select_widget_new (const gchar *title,
GimpRunBrushCallback callback,
gpointer data)
{
BrushSelect *brush_sel;
GtkWidget *frame;
GtkWidget *hbox;
gint mask_bpp;
gint mask_data_size;
gint color_bpp;
gint color_data_size;
guint8 *color_data;
GtkWidget *brush_button;
CompatCallbackData *compat_data;
g_return_val_if_fail (callback != NULL, NULL);
if (! title)
title = _("Brush Selection");
brush_button = gimp_brush_select_button_new (title, brush_name,
opacity, spacing, paint_mode);
brush_sel = g_new0 (BrushSelect, 1);
compat_data = g_new (CompatCallbackData, 1);
compat_data->callback = callback;
compat_data->data = data;
brush_sel->title = g_strdup (title);
brush_sel->callback = callback;
brush_sel->data = data;
g_signal_connect_data (brush_button, "brush-set",
G_CALLBACK (compat_callback),
compat_data, (GClosureNotify) g_free, 0);
hbox = gtk_hbox_new (FALSE, 6);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
brush_sel->preview = gimp_preview_area_new ();
gtk_widget_add_events (brush_sel->preview,
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
gtk_widget_set_size_request (brush_sel->preview, CELL_SIZE, CELL_SIZE);
gtk_container_add (GTK_CONTAINER (frame), brush_sel->preview);
gtk_widget_show (brush_sel->preview);
g_signal_connect_swapped (brush_sel->preview, "size-allocate",
G_CALLBACK (gimp_brush_select_preview_resize),
brush_sel);
g_signal_connect (brush_sel->preview, "event",
G_CALLBACK (gimp_brush_select_preview_events),
brush_sel);
gtk_drag_dest_set (GTK_WIDGET (brush_sel->preview),
GTK_DEST_DEFAULT_HIGHLIGHT |
GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_DROP,
&target, 1,
GDK_ACTION_COPY);
g_signal_connect (brush_sel->preview, "drag-data-received",
G_CALLBACK (gimp_brush_select_drag_data_received),
hbox);
brush_sel->button = gtk_button_new_with_mnemonic (_("_Browse..."));
gtk_box_pack_end (GTK_BOX (hbox), brush_sel->button, TRUE, TRUE, 0);
gtk_widget_show (brush_sel->button);
g_signal_connect (brush_sel->button, "clicked",
G_CALLBACK (gimp_brush_select_widget_clicked),
brush_sel);
g_signal_connect (brush_sel->button, "destroy",
G_CALLBACK (gimp_brush_select_widget_destroy),
brush_sel);
/* Do initial brush setup */
if (! brush_name || ! strlen (brush_name))
brush_sel->brush_name = gimp_context_get_brush ();
else
brush_sel->brush_name = g_strdup (brush_name);
if (gimp_brush_get_pixels (brush_sel->brush_name,
&brush_sel->width,
&brush_sel->height,
&mask_bpp,
&mask_data_size,
&brush_sel->mask_data,
&color_bpp,
&color_data_size,
&color_data))
{
if (color_data)
g_free (color_data);
if (opacity == -1)
brush_sel->opacity = gimp_context_get_opacity ();
else
brush_sel->opacity = opacity;
if (paint_mode == -1)
brush_sel->paint_mode = gimp_context_get_paint_mode ();
else
brush_sel->paint_mode = paint_mode;
if (spacing == -1)
gimp_brush_get_spacing (brush_sel->brush_name, &brush_sel->spacing);
else
brush_sel->spacing = spacing;
}
g_object_set_data (G_OBJECT (hbox), BRUSH_SELECT_DATA_KEY, brush_sel);
return hbox;
return brush_button;
}
/**
@ -237,17 +104,9 @@ gimp_brush_select_widget_new (const gchar *title,
void
gimp_brush_select_widget_close (GtkWidget *widget)
{
BrushSelect *brush_sel;
g_return_if_fail (widget != NULL);
brush_sel = g_object_get_data (G_OBJECT (widget), BRUSH_SELECT_DATA_KEY);
g_return_if_fail (brush_sel != NULL);
if (brush_sel->temp_brush_callback)
{
gimp_brush_select_destroy (brush_sel->temp_brush_callback);
brush_sel->temp_brush_callback = NULL;
}
gimp_select_button_close_popup (GIMP_SELECT_BUTTON (widget));
}
/**
@ -269,365 +128,29 @@ gimp_brush_select_widget_set (GtkWidget *widget,
gint spacing,
GimpLayerModeEffects paint_mode)
{
BrushSelect *brush_sel;
g_return_if_fail (widget != NULL);
brush_sel = g_object_get_data (G_OBJECT (widget), BRUSH_SELECT_DATA_KEY);
g_return_if_fail (brush_sel != NULL);
if (brush_sel->temp_brush_callback)
{
gimp_brushes_set_popup (brush_sel->temp_brush_callback,
brush_name, opacity, spacing, paint_mode);
}
else
{
gchar *name;
gint width;
gint height;
gint mask_bpp;
gint mask_data_size;
guint8 *mask_data;
gint color_bpp;
gint color_data_size;
guint8 *color_data;
if (! brush_name || ! strlen (brush_name))
name = gimp_context_get_brush ();
else
name = g_strdup (brush_name);
if (gimp_brush_get_pixels (name,
&width,
&height,
&mask_bpp,
&mask_data_size,
&mask_data,
&color_bpp,
&color_data_size,
&color_data))
{
if (color_data)
g_free (color_data);
if (opacity < 0.0)
opacity = gimp_context_get_opacity ();
if (paint_mode == -1)
paint_mode = gimp_context_get_paint_mode ();
if (spacing == -1)
gimp_brush_get_spacing (name, &spacing);
gimp_brush_select_widget_callback (name, opacity, spacing,
paint_mode, width, height,
mask_data, FALSE, brush_sel);
g_free (mask_data);
}
g_free (name);
}
}
/* private functions */
static void
gimp_brush_select_widget_callback (const gchar *name,
gdouble opacity,
gint spacing,
GimpLayerModeEffects paint_mode,
gint width,
gint height,
const guchar *mask_data,
gboolean closing,
gpointer data)
{
BrushSelect *brush_sel = (BrushSelect *) data;
g_free (brush_sel->brush_name);
g_free (brush_sel->mask_data);
brush_sel->brush_name = g_strdup (name);
brush_sel->width = width;
brush_sel->height = height;
brush_sel->mask_data = g_memdup (mask_data, width * height);
brush_sel->opacity = opacity;
brush_sel->spacing = spacing;
brush_sel->paint_mode = paint_mode;
gimp_brush_select_preview_update (brush_sel->preview,
width, height, mask_data);
if (brush_sel->callback)
brush_sel->callback (name, opacity, spacing, paint_mode,
width, height, mask_data, closing, brush_sel->data);
if (closing)
brush_sel->temp_brush_callback = NULL;
}
static void
gimp_brush_select_widget_clicked (GtkWidget *widget,
BrushSelect *brush_sel)
{
if (brush_sel->temp_brush_callback)
{
/* calling gimp_brushes_set_popup() raises the dialog */
gimp_brushes_set_popup (brush_sel->temp_brush_callback,
brush_sel->brush_name,
brush_sel->opacity,
brush_sel->spacing,
brush_sel->paint_mode);
}
else
{
brush_sel->temp_brush_callback =
gimp_brush_select_new (brush_sel->title,
brush_sel->brush_name,
brush_sel->opacity,
brush_sel->spacing,
brush_sel->paint_mode,
gimp_brush_select_widget_callback,
brush_sel);
}
}
static void
gimp_brush_select_widget_destroy (GtkWidget *widget,
BrushSelect *brush_sel)
{
if (brush_sel->temp_brush_callback)
{
gimp_brush_select_destroy (brush_sel->temp_brush_callback);
brush_sel->temp_brush_callback = NULL;
}
g_free (brush_sel->title);
g_free (brush_sel->brush_name);
g_free (brush_sel->mask_data);
g_free (brush_sel);
gimp_brush_select_button_set_brush
(GIMP_BRUSH_SELECT_BUTTON (widget), brush_name,
opacity, spacing, paint_mode);
}
static void
gimp_brush_select_preview_resize (BrushSelect *brush_sel)
compat_callback (GimpBrushSelectButton *brush_button,
const gchar *brush_name,
gdouble opacity,
gint spacing,
GimpLayerModeEffects paint_mode,
gint width,
gint height,
const guchar *mask_data,
gboolean dialog_closing,
gpointer data)
{
if (brush_sel->width > 0 && brush_sel->height > 0)
gimp_brush_select_preview_update (brush_sel->preview,
brush_sel->width,
brush_sel->height,
brush_sel->mask_data);
CompatCallbackData *compat_data = data;
}
static gboolean
gimp_brush_select_preview_events (GtkWidget *widget,
GdkEvent *event,
BrushSelect *brush_sel)
{
GdkEventButton *bevent;
if (brush_sel->mask_data)
{
switch (event->type)
{
case GDK_BUTTON_PRESS:
bevent = (GdkEventButton *) event;
if (bevent->button == 1)
{
gtk_grab_add (widget);
gimp_brush_select_popup_open (brush_sel, bevent->x, bevent->y);
}
break;
case GDK_BUTTON_RELEASE:
bevent = (GdkEventButton *) event;
if (bevent->button == 1)
{
gtk_grab_remove (widget);
gimp_brush_select_popup_close (brush_sel);
}
break;
default:
break;
}
}
return FALSE;
}
static void
gimp_brush_select_preview_draw (GimpPreviewArea *area,
gint x,
gint y,
gint width,
gint height,
const guchar *mask_data,
gint rowstride)
{
const guchar *src;
guchar *dest;
guchar *buf;
gint i, j;
buf = g_new (guchar, width * height);
src = mask_data;
dest = buf;
for (j = 0; j < height; j++)
{
const guchar *s = src;
for (i = 0; i < width; i++, s++, dest++)
*dest = 255 - *s;
src += rowstride;
}
gimp_preview_area_draw (area,
x, y, width, height,
GIMP_GRAY_IMAGE,
buf,
width);
g_free (buf);
}
static void
gimp_brush_select_preview_update (GtkWidget *preview,
gint brush_width,
gint brush_height,
const guchar *mask_data)
{
GimpPreviewArea *area = GIMP_PREVIEW_AREA (preview);
gint x, y;
gint width, height;
width = MIN (brush_width, preview->allocation.width);
height = MIN (brush_height, preview->allocation.height);
x = ((preview->allocation.width - width) / 2);
y = ((preview->allocation.height - height) / 2);
if (x || y)
gimp_preview_area_fill (area,
0, 0,
preview->allocation.width,
preview->allocation.height,
0xFF, 0xFF, 0xFF);
gimp_brush_select_preview_draw (area,
x, y, width, height,
mask_data, brush_width);
}
static void
gimp_brush_select_popup_open (BrushSelect *brush_sel,
gint x,
gint y)
{
GtkWidget *frame;
GtkWidget *preview;
GdkScreen *screen;
gint x_org;
gint y_org;
gint scr_w;
gint scr_h;
if (brush_sel->popup)
gimp_brush_select_popup_close (brush_sel);
if (brush_sel->width <= CELL_SIZE && brush_sel->height <= CELL_SIZE)
return;
brush_sel->popup = gtk_window_new (GTK_WINDOW_POPUP);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (brush_sel->popup), frame);
gtk_widget_show (frame);
preview = gimp_preview_area_new ();
gtk_widget_set_size_request (preview, brush_sel->width, brush_sel->height);
gtk_container_add (GTK_CONTAINER (frame), preview);
gtk_widget_show (preview);
/* decide where to put the popup */
gdk_window_get_origin (brush_sel->preview->window, &x_org, &y_org);
screen = gtk_widget_get_screen (brush_sel->popup);
scr_w = gdk_screen_get_width (screen);
scr_h = gdk_screen_get_height (screen);
x = x_org + x - (brush_sel->width / 2);
y = y_org + y - (brush_sel->height / 2);
x = (x < 0) ? 0 : x;
y = (y < 0) ? 0 : y;
x = (x + brush_sel->width > scr_w) ? scr_w - brush_sel->width : x;
y = (y + brush_sel->height > scr_h) ? scr_h - brush_sel->height : y;
gtk_window_move (GTK_WINDOW (brush_sel->popup), x, y);
gtk_widget_show (brush_sel->popup);
/* Draw the brush */
gimp_brush_select_preview_draw (GIMP_PREVIEW_AREA (preview),
0, 0, brush_sel->width, brush_sel->height,
brush_sel->mask_data, brush_sel->width);
}
static void
gimp_brush_select_popup_close (BrushSelect *brush_sel)
{
if (brush_sel->popup)
{
gtk_widget_destroy (brush_sel->popup);
brush_sel->popup = NULL;
}
}
static void
gimp_brush_select_drag_data_received (GtkWidget *preview,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time,
GtkWidget *widget)
{
gchar *str;
if ((selection->format != 8) || (selection->length < 1))
{
g_warning ("Received invalid brush data!");
return;
}
str = g_strndup ((const gchar *) selection->data, selection->length);
if (g_utf8_validate (str, -1, NULL))
{
gint pid;
gpointer unused;
gint name_offset = 0;
if (sscanf (str, "%i:%p:%n", &pid, &unused, &name_offset) >= 2 &&
pid == gimp_getpid () && name_offset > 0)
{
gchar *name = str + name_offset;
gimp_brush_select_widget_set (widget, name, -1.0, -1, -1);
}
}
g_free (str);
compat_data->callback (brush_name, opacity, spacing, paint_mode,
width, height, mask_data,
dialog_closing, compat_data->data);
}

View File

@ -22,6 +22,12 @@
#ifndef __GIMP_BRUSH_MENU_H__
#define __GIMP_BRUSH_MENU_H__
/* These functions are deprecated and should not be used in newly
* written code.
*/
#ifndef GIMP_DISABLE_DEPRECATED
G_BEGIN_DECLS
@ -43,4 +49,6 @@ void gimp_brush_select_widget_set (GtkWidget *widget,
G_END_DECLS
#endif /* GIMP_DISABLE_DEPRECATED */
#endif /* __GIMP_BRUSH_MENU_H__ */

View File

@ -0,0 +1,912 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimpbrushselectbutton.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 <gtk/gtk.h>
#include "libgimpwidgets/gimpwidgets.h"
#include "gimp.h"
#include "gimpuitypes.h"
#include "gimpbrushselectbutton.h"
#include "gimpuimarshal.h"
#include "libgimp-intl.h"
#define CELL_SIZE 20
#define GIMP_BRUSH_SELECT_BUTTON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GIMP_TYPE_BRUSH_SELECT_BUTTON, GimpBrushSelectButtonPrivate))
typedef struct _GimpBrushSelectButtonPrivate GimpBrushSelectButtonPrivate;
struct _GimpBrushSelectButtonPrivate
{
gchar *title;
gchar *brush_name; /* Local copy */
gdouble opacity;
gint spacing;
GimpLayerModeEffects paint_mode;
gint width;
gint height;
guchar *mask_data; /* local copy */
GtkWidget *inside;
GtkWidget *preview;
GtkWidget *popup;
};
enum
{
BRUSH_SET,
LAST_SIGNAL
};
enum
{
PROP_0,
PROP_TITLE,
PROP_BRUSH_NAME,
PROP_BRUSH_OPACITY,
PROP_BRUSH_SPACING,
PROP_BRUSH_PAINT_MODE
};
/* local function prototypes */
static void gimp_brush_select_button_finalize (GObject *object);
static void gimp_brush_select_button_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_brush_select_button_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_brush_select_button_clicked (GimpBrushSelectButton *brush_button);
static void gimp_brush_select_button_callback (const gchar *brush_name,
gdouble opacity,
gint spacing,
GimpLayerModeEffects paint_mode,
gint width,
gint height,
const guchar *mask_data,
gboolean dialog_closing,
gpointer user_data);
static void gimp_brush_select_preview_resize (GimpBrushSelectButton *brush_button);
static gboolean gimp_brush_select_preview_events (GtkWidget *widget,
GdkEvent *event,
GimpBrushSelectButton *brush_button);
static void gimp_brush_select_preview_draw (GimpPreviewArea *area,
gint x,
gint y,
gint width,
gint height,
const guchar *mask_data,
gint rowstride);
static void gimp_brush_select_preview_update (GtkWidget *preview,
gint brush_width,
gint brush_height,
const guchar *mask_data);
static void gimp_brush_select_button_open_popup (GimpBrushSelectButton *brush_button,
gint x,
gint y);
static void gimp_brush_select_button_close_popup (GimpBrushSelectButton *brush_button);
static void gimp_brush_select_drag_data_received (GimpBrushSelectButton *brush_button,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time);
static GtkWidget * gimp_brush_select_button_create_inside (GimpBrushSelectButton *brush_button);
static const GtkTargetEntry target = { "application/x-gimp-brush-name", 0 };
static guint brush_button_signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (GimpBrushSelectButton, gimp_brush_select_button,
GIMP_TYPE_SELECT_BUTTON)
static void
gimp_brush_select_button_class_init (GimpBrushSelectButtonClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpSelectButtonClass *select_button_class = GIMP_SELECT_BUTTON_CLASS (klass);
object_class->finalize = gimp_brush_select_button_finalize;
object_class->set_property = gimp_brush_select_button_set_property;
object_class->get_property = gimp_brush_select_button_get_property;
select_button_class->select_destroy = gimp_brush_select_destroy;
klass->brush_set = NULL;
/**
* GimpBrushSelectButton:title:
*
* The title to be used for the brush selection popup dialog.
*
* Since: GIMP 2.4
*/
g_object_class_install_property (object_class, PROP_TITLE,
g_param_spec_string ("title",
"Title",
"The title to be used for the brush selection popup dialog",
_("Brush Selection"),
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
/**
* GimpBrushSelectButton:brush-name:
*
* The name of the currently selected brush.
*
* Since: GIMP 2.4
*/
g_object_class_install_property (object_class, PROP_BRUSH_NAME,
g_param_spec_string ("brush-name",
"Brush name",
"The name of the currently selected brush",
NULL,
GIMP_PARAM_READWRITE));
/**
* GimpBrushSelectButton:opacity:
*
* The opacity of the currently selected brush.
*
* Since: GIMP 2.4
*/
g_object_class_install_property (object_class, PROP_BRUSH_OPACITY,
g_param_spec_double ("brush-opacity",
"Brush opacity",
"The opacity of the currently selected brush",
-1.0, 100.0, -1.0,
GIMP_PARAM_READWRITE));
/**
* GimpBrushSelectButton:spacing:
*
* The spacing of the currently selected brush.
*
* Since: GIMP 2.4
*/
g_object_class_install_property (object_class, PROP_BRUSH_SPACING,
g_param_spec_int ("brush-spacing",
"Brush spacing",
"The spacing of the currently selected brush",
-G_MAXINT, 1000, -1,
GIMP_PARAM_READWRITE));
/**
* GimpBrushSelectButton:paint-mode:
*
* The name of the currently selected brush.
*
* Since: GIMP 2.4
*/
g_object_class_install_property (object_class, PROP_BRUSH_PAINT_MODE,
g_param_spec_int ("brush-paint-mode",
"Brush paint mode",
"The paint mode of the currently selected brush",
-1, GIMP_COLOR_ERASE_MODE,
-1,
GIMP_PARAM_READWRITE));
/**
* GimpBrushSelectButton::brush-set:
* @widget: the object which received the signal.
* @brush_name: the name of the currently selected brush.
* @opacity: opacity of the brush
* @spacing: spacing of the brush
* @paint_mode: paint mode of the brush
* @width: width of the brush
* @height: height of the brush
* @mask_data: brush mask data
* @dialog_closing: whether the dialog was closed or not.
*
* The ::brush-set signal is emitted when the user selects a brush.
*
* Since: GIMP 2.4
*/
brush_button_signals[BRUSH_SET] =
g_signal_new ("brush-set",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpBrushSelectButtonClass, brush_set),
NULL, NULL,
_gimpui_marshal_VOID__STRING_DOUBLE_INT_INT_INT_INT_POINTER_BOOLEAN,
G_TYPE_NONE, 8,
G_TYPE_STRING,
G_TYPE_DOUBLE,
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_POINTER,
G_TYPE_BOOLEAN);
g_type_class_add_private (object_class,
sizeof (GimpBrushSelectButtonPrivate));
}
static void
gimp_brush_select_button_init (GimpBrushSelectButton *brush_button)
{
GimpBrushSelectButtonPrivate *priv;
gint mask_bpp;
gint mask_data_size;
gint color_bpp;
gint color_data_size;
guint8 *color_data;
priv = GIMP_BRUSH_SELECT_BUTTON_GET_PRIVATE (brush_button);
priv->brush_name = gimp_context_get_brush ();
gimp_brush_get_pixels (priv->brush_name,
&priv->width,
&priv->height,
&mask_bpp,
&mask_data_size,
&priv->mask_data,
&color_bpp,
&color_data_size,
&color_data);
priv->inside = gimp_brush_select_button_create_inside (brush_button);
gtk_container_add (GTK_CONTAINER (brush_button), priv->inside);
priv->popup = NULL;
}
/**
* gimp_brush_select_button_new:
* @title: Title of the dialog to use or %NULL means to use the default
* title.
* @brush_name: Initial brush name or %NULL to use current selection.
* @opacity: Initial opacity. -1 means to use current opacity.
* @spacing: Initial spacing. -1 means to use current spacing.
* @paint_mode: Initial paint mode. -1 means to use current paint mode.
*
* Creates a new #GtkWidget that completely controls the selection of
* a #GimpBrush. This widget is suitable for placement in a table in
* a plug-in dialog.
*
* Returns: A #GtkWidget that you can use in your UI.
*
* Since: GIMP 2.4
*/
GtkWidget *
gimp_brush_select_button_new (const gchar *title,
const gchar *brush_name,
gdouble opacity,
gint spacing,
GimpLayerModeEffects paint_mode)
{
GtkWidget *brush_button;
if (title)
brush_button = g_object_new (GIMP_TYPE_BRUSH_SELECT_BUTTON,
"title", title,
"brush-name", brush_name,
"brush-opacity", opacity,
"brush-spacing", spacing,
"brush-paint-mode", paint_mode,
NULL);
else
brush_button = g_object_new (GIMP_TYPE_BRUSH_SELECT_BUTTON,
"brush-name", brush_name,
"brush-opacity", opacity,
"brush-spacing", spacing,
"brush-paint-mode", paint_mode,
NULL);
return brush_button;
}
/**
* gimp_brush_select_button_get_brush:
* @button: A #GimpBrushSelectButton
* @opacity: Opacity of the selected brush.
* @spacing: Spacing of the selected brush.
* @paint_mode: Paint mode of the selected brush.
*
* Retrieves the properties of currently selected brush.
*
* Returns: an internal copy of the brush name which must not be freed.
*
* Since: GIMP 2.4
*/
G_CONST_RETURN gchar *
gimp_brush_select_button_get_brush (GimpBrushSelectButton *brush_button,
gdouble *opacity,
gint *spacing,
GimpLayerModeEffects *paint_mode)
{
GimpBrushSelectButtonPrivate *priv;
g_return_val_if_fail (GIMP_IS_BRUSH_SELECT_BUTTON (brush_button), NULL);
if (opacity)
*opacity = priv->opacity;
if (spacing)
*spacing = priv->spacing;
if (paint_mode)
*paint_mode = priv->paint_mode;
priv = GIMP_BRUSH_SELECT_BUTTON_GET_PRIVATE (brush_button);
return priv->brush_name;
}
/**
* gimp_brush_select_button_set_brush:
* @brush_button: A #GimpBrushSelectButton
* @brush_name: Brush name to set; %NULL means no change.
* @opacity: Opacity to set. -1.0 means no change.
* @spacing: Spacing to set. -1 means no change.
* @paint_mode: Paint mode to set. -1 means no change.
*
* Sets the current brush and other values for the brush select
* button.
*
* Since: GIMP 2.4
*/
void
gimp_brush_select_button_set_brush (GimpBrushSelectButton *brush_button,
const gchar *brush_name,
gdouble opacity,
gint spacing,
GimpLayerModeEffects paint_mode)
{
GimpSelectButton *select_button;
g_return_if_fail (GIMP_IS_BRUSH_SELECT_BUTTON (brush_button));
select_button = GIMP_SELECT_BUTTON (brush_button);
if (select_button->temp_callback)
{
gimp_brushes_set_popup (select_button->temp_callback, brush_name,
opacity, spacing, paint_mode);
}
else
{
gchar *name;
gint width;
gint height;
gint bytes;
gint mask_data_size;
guint8 *mask_data;
gint color_bpp;
gint color_data_size;
guint8 *color_data;
if (brush_name && *brush_name)
name = g_strdup (brush_name);
else
name = gimp_context_get_brush ();
if (gimp_brush_get_pixels (name,
&width,
&height,
&bytes,
&mask_data_size,
&mask_data,
&color_bpp,
&color_data_size,
&color_data))
{
if (color_data)
g_free (color_data);
if (opacity < 0.0)
opacity = gimp_context_get_opacity ();
if (spacing == -1)
gimp_brush_get_spacing (name, &spacing);
if (paint_mode == -1)
paint_mode = gimp_context_get_paint_mode ();
gimp_brush_select_button_callback (name,
opacity, spacing, paint_mode,
width, height, mask_data,
FALSE, brush_button);
g_free (mask_data);
}
g_free (name);
}
}
/* private functions */
static void
gimp_brush_select_button_finalize (GObject *object)
{
GimpBrushSelectButtonPrivate *priv;
priv = GIMP_BRUSH_SELECT_BUTTON_GET_PRIVATE (object);
g_free (priv->brush_name);
priv->brush_name = NULL;
g_free (priv->mask_data);
priv->mask_data = NULL;
g_free (priv->title);
priv->title = NULL;
G_OBJECT_CLASS (gimp_brush_select_button_parent_class)->finalize (object);
}
static void
gimp_brush_select_button_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpBrushSelectButton *brush_button;
GimpBrushSelectButtonPrivate *priv;
brush_button = GIMP_BRUSH_SELECT_BUTTON (object);
priv = GIMP_BRUSH_SELECT_BUTTON_GET_PRIVATE (brush_button);
switch (property_id)
{
case PROP_TITLE:
priv->title = g_value_dup_string (value);
break;
case PROP_BRUSH_NAME:
gimp_brush_select_button_set_brush (brush_button,
g_value_get_string (value),
-1.0, -1, -1);
break;
case PROP_BRUSH_OPACITY:
priv->opacity = g_value_get_double (value);
break;
case PROP_BRUSH_SPACING:
priv->spacing = g_value_get_int (value);
break;
case PROP_BRUSH_PAINT_MODE:
priv->paint_mode = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_brush_select_button_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpBrushSelectButton *brush_button;
GimpBrushSelectButtonPrivate *priv;
brush_button = GIMP_BRUSH_SELECT_BUTTON (object);
priv = GIMP_BRUSH_SELECT_BUTTON_GET_PRIVATE (brush_button);
switch (property_id)
{
case PROP_TITLE:
g_value_set_string (value, priv->title);
break;
case PROP_BRUSH_NAME:
g_value_set_string (value, priv->brush_name);
break;
case PROP_BRUSH_OPACITY:
g_value_set_double (value, priv->opacity);
break;
case PROP_BRUSH_SPACING:
g_value_set_int (value, priv->spacing);
break;
case PROP_BRUSH_PAINT_MODE:
g_value_set_int (value, priv->paint_mode);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_brush_select_button_callback (const gchar *name,
gdouble opacity,
gint spacing,
GimpLayerModeEffects paint_mode,
gint width,
gint height,
const guchar *mask_data,
gboolean dialog_closing,
gpointer data)
{
GimpBrushSelectButton *brush_button;
GimpBrushSelectButtonPrivate *priv;
GimpSelectButton *select_button;
brush_button = GIMP_BRUSH_SELECT_BUTTON (data);
priv = GIMP_BRUSH_SELECT_BUTTON_GET_PRIVATE (brush_button);
select_button = GIMP_SELECT_BUTTON (brush_button);
g_free (priv->brush_name);
g_free (priv->mask_data);
priv->brush_name = g_strdup (name);
priv->width = width;
priv->height = height;
priv->mask_data = g_memdup (mask_data, width * height);
priv->opacity = opacity;
priv->spacing = spacing;
priv->paint_mode = paint_mode;
gimp_brush_select_preview_update (priv->preview,
width, height, mask_data);
if (dialog_closing)
select_button->temp_callback = NULL;
g_signal_emit (brush_button, brush_button_signals[BRUSH_SET], 0,
name, opacity, spacing, paint_mode, width, height, mask_data,
dialog_closing);
g_object_notify (G_OBJECT (brush_button), "brush-name");
}
static void
gimp_brush_select_button_clicked (GimpBrushSelectButton *brush_button)
{
GimpBrushSelectButtonPrivate *priv;
GimpSelectButton *select_button;
priv = GIMP_BRUSH_SELECT_BUTTON_GET_PRIVATE (brush_button);
select_button = GIMP_SELECT_BUTTON (brush_button);
if (select_button->temp_callback)
{
/* calling gimp_brushes_set_popup() raises the dialog */
gimp_brushes_set_popup (select_button->temp_callback,
priv->brush_name,
priv->opacity,
priv->spacing,
priv->paint_mode);
}
else
{
select_button->temp_callback =
gimp_brush_select_new (priv->title, priv->brush_name,
priv->opacity, priv->spacing, priv->paint_mode,
gimp_brush_select_button_callback,
brush_button);
}
}
static void
gimp_brush_select_preview_resize (GimpBrushSelectButton *brush_button)
{
GimpBrushSelectButtonPrivate *priv;
priv = GIMP_BRUSH_SELECT_BUTTON_GET_PRIVATE (brush_button);
if (priv->width > 0 && priv->height > 0)
gimp_brush_select_preview_update (priv->preview,
priv->width,
priv->height,
priv->mask_data);
}
static gboolean
gimp_brush_select_preview_events (GtkWidget *widget,
GdkEvent *event,
GimpBrushSelectButton *brush_button)
{
GimpBrushSelectButtonPrivate *priv;
GdkEventButton *bevent;
priv = GIMP_BRUSH_SELECT_BUTTON_GET_PRIVATE (brush_button);
if (priv->mask_data)
{
switch (event->type)
{
case GDK_BUTTON_PRESS:
bevent = (GdkEventButton *) event;
if (bevent->button == 1)
{
gtk_grab_add (widget);
gimp_brush_select_button_open_popup (brush_button,
bevent->x, bevent->y);
}
break;
case GDK_BUTTON_RELEASE:
bevent = (GdkEventButton *) event;
if (bevent->button == 1)
{
gtk_grab_remove (widget);
gimp_brush_select_button_close_popup (brush_button);
}
break;
default:
break;
}
}
return FALSE;
}
static void
gimp_brush_select_preview_draw (GimpPreviewArea *area,
gint x,
gint y,
gint width,
gint height,
const guchar *mask_data,
gint rowstride)
{
const guchar *src;
guchar *dest;
guchar *buf;
gint i, j;
buf = g_new (guchar, width * height);
src = mask_data;
dest = buf;
for (j = 0; j < height; j++)
{
const guchar *s = src;
for (i = 0; i < width; i++, s++, dest++)
*dest = 255 - *s;
src += rowstride;
}
gimp_preview_area_draw (area,
x, y, width, height,
GIMP_GRAY_IMAGE,
buf,
width);
g_free (buf);
}
static void
gimp_brush_select_preview_update (GtkWidget *preview,
gint brush_width,
gint brush_height,
const guchar *mask_data)
{
GimpPreviewArea *area = GIMP_PREVIEW_AREA (preview);
gint x, y;
gint width, height;
width = MIN (brush_width, preview->allocation.width);
height = MIN (brush_height, preview->allocation.height);
x = ((preview->allocation.width - width) / 2);
y = ((preview->allocation.height - height) / 2);
if (x || y)
gimp_preview_area_fill (area,
0, 0,
preview->allocation.width,
preview->allocation.height,
0xFF, 0xFF, 0xFF);
gimp_brush_select_preview_draw (area,
x, y, width, height,
mask_data, brush_width);
}
static void
gimp_brush_select_button_open_popup (GimpBrushSelectButton *brush_button,
gint x,
gint y)
{
GimpBrushSelectButtonPrivate *priv;
GtkWidget *frame;
GtkWidget *preview;
GdkScreen *screen;
gint x_org;
gint y_org;
gint scr_w;
gint scr_h;
priv = GIMP_BRUSH_SELECT_BUTTON_GET_PRIVATE (brush_button);
if (priv->popup)
gimp_brush_select_button_close_popup (brush_button);
if (priv->width <= CELL_SIZE && priv->height <= CELL_SIZE)
return;
priv->popup = gtk_window_new (GTK_WINDOW_POPUP);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (priv->popup), frame);
gtk_widget_show (frame);
preview = gimp_preview_area_new ();
gtk_widget_set_size_request (preview, priv->width, priv->height);
gtk_container_add (GTK_CONTAINER (frame), preview);
gtk_widget_show (preview);
/* decide where to put the popup */
gdk_window_get_origin (priv->preview->window, &x_org, &y_org);
screen = gtk_widget_get_screen (priv->popup);
scr_w = gdk_screen_get_width (screen);
scr_h = gdk_screen_get_height (screen);
x = x_org + x - (priv->width / 2);
y = y_org + y - (priv->height / 2);
x = (x < 0) ? 0 : x;
y = (y < 0) ? 0 : y;
x = (x + priv->width > scr_w) ? scr_w - priv->width : x;
y = (y + priv->height > scr_h) ? scr_h - priv->height : y;
gtk_window_move (GTK_WINDOW (priv->popup), x, y);
gtk_widget_show (priv->popup);
/* Draw the brush */
gimp_brush_select_preview_draw (GIMP_PREVIEW_AREA (preview),
0, 0, priv->width, priv->height,
priv->mask_data, priv->width);
}
static void
gimp_brush_select_button_close_popup (GimpBrushSelectButton *brush_button)
{
GimpBrushSelectButtonPrivate *priv;
priv = GIMP_BRUSH_SELECT_BUTTON_GET_PRIVATE (brush_button);
if (priv->popup)
{
gtk_widget_destroy (priv->popup);
priv->popup = NULL;
}
}
static void
gimp_brush_select_drag_data_received (GimpBrushSelectButton *brush_button,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time)
{
gchar *str;
if ((selection->format != 8) || (selection->length < 1))
{
g_warning ("Received invalid brush data!");
return;
}
str = g_strndup ((const gchar *) selection->data, selection->length);
if (g_utf8_validate (str, -1, NULL))
{
gint pid;
gpointer unused;
gint name_offset = 0;
if (sscanf (str, "%i:%p:%n", &pid, &unused, &name_offset) >= 2 &&
pid == gimp_getpid () && name_offset > 0)
{
gchar *name = str + name_offset;
gimp_brush_select_button_set_brush (brush_button, name, -1.0, -1, -1);
}
}
g_free (str);
}
static GtkWidget *
gimp_brush_select_button_create_inside (GimpBrushSelectButton *brush_button)
{
GtkWidget *hbox;
GtkWidget *frame;
GtkWidget *button;
GimpBrushSelectButtonPrivate *priv;
priv = GIMP_BRUSH_SELECT_BUTTON_GET_PRIVATE (brush_button);
gtk_widget_push_composite_child ();
hbox = gtk_hbox_new (FALSE, 6);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0);
priv->preview = gimp_preview_area_new ();
gtk_widget_add_events (priv->preview,
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
gtk_widget_set_size_request (priv->preview, CELL_SIZE, CELL_SIZE);
gtk_container_add (GTK_CONTAINER (frame), priv->preview);
g_signal_connect_swapped (priv->preview, "size-allocate",
G_CALLBACK (gimp_brush_select_preview_resize),
brush_button);
g_signal_connect (priv->preview, "event",
G_CALLBACK (gimp_brush_select_preview_events),
brush_button);
gtk_drag_dest_set (GTK_WIDGET (priv->preview),
GTK_DEST_DEFAULT_HIGHLIGHT |
GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_DROP,
&target, 1,
GDK_ACTION_COPY);
g_signal_connect (priv->preview, "drag-data-received",
G_CALLBACK (gimp_brush_select_drag_data_received),
hbox);
button = gtk_button_new_with_mnemonic (_("_Browse..."));
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gimp_brush_select_button_clicked),
brush_button);
gtk_widget_show_all (hbox);
gtk_widget_pop_composite_child ();
return hbox;
}

View File

@ -0,0 +1,91 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimpbrushselectbutton.h
*
* 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
* Lesser 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.
*/
#ifndef __GIMP_BRUSH_SELECT_BUTTON_H__
#define __GIMP_BRUSH_SELECT_BUTTON_H__
#include <libgimp/gimpselectbutton.h>
G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
#define GIMP_TYPE_BRUSH_SELECT_BUTTON (gimp_brush_select_button_get_type ())
#define GIMP_BRUSH_SELECT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_BRUSH_SELECT_BUTTON, GimpBrushSelectButton))
#define GIMP_BRUSH_SELECT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_BRUSH_SELECT_BUTTON, GimpBrushSelectButtonClass))
#define GIMP_IS_BRUSH_SELECT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_BRUSH_SELECT_BUTTON))
#define GIMP_IS_BRUSH_SELECT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_BRUSH_SELECT_BUTTON))
#define GIMP_BRUSH_SELECT_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_BRUSH_SELECT_BUTTON, GimpBrushSelectButtonClass))
typedef struct _GimpBrushSelectButtonClass GimpBrushSelectButtonClass;
struct _GimpBrushSelectButton
{
GimpSelectButton parent_instance;
};
struct _GimpBrushSelectButtonClass
{
GimpSelectButtonClass parent_class;
/* brush_set signal is emitted when brush is chosen */
void (* brush_set) (GimpBrushSelectButton *brush_button,
const gchar *brush_name,
gdouble opacity,
gint spacing,
GimpLayerModeEffects paint_mode,
gint width,
gint height,
const guchar *mask_data,
gboolean dialog_closing);
/* Padding for future expansion */
void (*_gimp_reserved1) (void);
void (*_gimp_reserved2) (void);
void (*_gimp_reserved3) (void);
void (*_gimp_reserved4) (void);
};
GType gimp_brush_select_button_get_type (void) G_GNUC_CONST;
GtkWidget * gimp_brush_select_button_new (const gchar *title,
const gchar *brush_name,
gdouble opacity,
gint spacing,
GimpLayerModeEffects paint_mode);
G_CONST_RETURN gchar * gimp_brush_select_button_get_brush (GimpBrushSelectButton *button,
gdouble *opacity,
gint *spacing,
GimpLayerModeEffects *paint_mode);
void gimp_brush_select_button_set_brush (GimpBrushSelectButton *button,
const gchar *brush_name,
gdouble opacity,
gint spacing,
GimpLayerModeEffects paint_mode);
G_END_DECLS
#endif /* __GIMP_BRUSH_SELECT_BUTTON_H__ */

View File

@ -23,7 +23,12 @@
#include "config.h"
#include "gimp.h"
#include "gimpui.h"
#include "gimpuitypes.h"
#include "gimpfontselectbutton.h"
#undef GIMP_DISABLE_DEPRECATED
#include "gimpfontmenu.h"
typedef struct _CompatCallbackData CompatCallbackData;
@ -43,8 +48,7 @@ static void compat_callback (GimpFontSelectButton *font_button,
/**
* gimp_font_select_widget_new:
* @title: Title of the dialog to use or %NULL means to use the default
* title.
* @title: Title of the dialog to use or %NULL to use the default title.
* @font_name: Initial font name.
* @callback: A function to call when the selected font changes.
* @data: A pointer to arbitary data to be used in the call to @callback.
@ -90,7 +94,7 @@ gimp_font_select_widget_close (GtkWidget *widget)
{
g_return_if_fail (widget != NULL);
gimp_font_select_button_close_popup (GIMP_FONT_SELECT_BUTTON (widget));
gimp_select_button_close_popup (GIMP_SELECT_BUTTON (widget));
}
/**

View File

@ -22,27 +22,32 @@
#include "config.h"
#include <gtk/gtk.h>
#include "libgimpwidgets/gimpwidgets.h"
#include "gimp.h"
#include "gimpui.h"
#include "gimpuitypes.h"
#include "gimpfontselectbutton.h"
#include "gimpuimarshal.h"
#include "libgimp-intl.h"
typedef struct
#define GIMP_FONT_SELECT_BUTTON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GIMP_TYPE_FONT_SELECT_BUTTON, GimpFontSelectButtonPrivate))
typedef struct _GimpFontSelectButtonPrivate GimpFontSelectButtonPrivate;
struct _GimpFontSelectButtonPrivate
{
gchar *title;
gchar *font_name; /* local copy */
GtkWidget *inside;
GtkWidget *label;
const gchar *temp_font_callback;
} GimpFontSelectButtonPrivate;
#define GIMP_FONT_SELECT_BUTTON_GET_PRIVATE(obj) \
((GimpFontSelectButtonPrivate *) ((GimpFontSelectButton *) (obj))->priv)
};
enum
{
@ -60,6 +65,8 @@ enum
/* local function prototypes */
static void gimp_font_select_button_finalize (GObject *object);
static void gimp_font_select_button_set_property (GObject *object,
guint property_id,
const GValue *value,
@ -69,19 +76,19 @@ static void gimp_font_select_button_get_property (GObject *object,
GValue *value,
GParamSpec *pspec);
static void gimp_font_select_button_destroy (GtkObject *object);
static void gimp_font_select_button_clicked (GtkButton *button);
static void gimp_font_select_button_callback (const gchar *name,
gboolean closing,
gpointer data);
static void gimp_font_select_button_clicked (GimpFontSelectButton *font_button);
static void gimp_font_select_drag_data_received (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time);
static void gimp_font_select_button_callback (const gchar *font_name,
gboolean dialog_closing,
gpointer user_data);
static void gimp_font_select_drag_data_received (GimpFontSelectButton *font_button,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time);
static GtkWidget * gimp_font_select_button_create_inside (GimpFontSelectButton *button);
@ -91,37 +98,35 @@ static const GtkTargetEntry target = { "application/x-gimp-font-name", 0 };
static guint font_button_signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (GimpFontSelectButton, gimp_font_select_button, GTK_TYPE_BUTTON)
G_DEFINE_TYPE (GimpFontSelectButton, gimp_font_select_button,
GIMP_TYPE_SELECT_BUTTON)
static void
gimp_font_select_button_class_init (GimpFontSelectButtonClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GtkButtonClass *button_class = GTK_BUTTON_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpSelectButtonClass *select_button_class = GIMP_SELECT_BUTTON_CLASS (klass);
gobject_class->set_property = gimp_font_select_button_set_property;
gobject_class->get_property = gimp_font_select_button_get_property;
object_class->finalize = gimp_font_select_button_finalize;
object_class->set_property = gimp_font_select_button_set_property;
object_class->get_property = gimp_font_select_button_get_property;
object_class->destroy = gimp_font_select_button_destroy;
widget_class->drag_data_received = gimp_font_select_drag_data_received;
button_class->clicked = gimp_font_select_button_clicked;
select_button_class->select_destroy = gimp_font_select_destroy;
klass->font_set = NULL;
/**
* GimpFontSelectButton:title:
*
* The title to be used for the font selection dialog.
* The title to be used for the font selection popup dialog.
*
* Since: GIMP 2.4
*/
g_object_class_install_property (gobject_class, PROP_TITLE,
g_param_spec_string ("title", NULL, NULL,
g_object_class_install_property (object_class, PROP_TITLE,
g_param_spec_string ("title",
"Title",
"The title to be used for the font selection popup dialog",
_("Font Selection"),
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
@ -131,10 +136,12 @@ gimp_font_select_button_class_init (GimpFontSelectButtonClass *klass)
*
* The name of the currently selected font.
*
* Since: 2.4
* Since: GIMP 2.4
*/
g_object_class_install_property (gobject_class, PROP_FONT_NAME,
g_param_spec_string ("font-name", NULL, NULL,
g_object_class_install_property (object_class, PROP_FONT_NAME,
g_param_spec_string ("font-name",
"Font name",
"The name of the currently selected font",
_("Sans"),
GIMP_PARAM_READWRITE));
@ -146,7 +153,7 @@ gimp_font_select_button_class_init (GimpFontSelectButtonClass *klass)
*
* The ::font-set signal is emitted when the user selects a font.
*
* Since: 2.4
* Since: GIMP 2.4
*/
font_button_signals[FONT_SET] =
g_signal_new ("font-set",
@ -159,39 +166,26 @@ gimp_font_select_button_class_init (GimpFontSelectButtonClass *klass)
G_TYPE_STRING,
G_TYPE_BOOLEAN);
g_type_class_add_private (object_class, sizeof (GimpFontSelectButtonPrivate));
g_type_class_add_private (object_class,
sizeof (GimpFontSelectButtonPrivate));
}
static void
gimp_font_select_button_init (GimpFontSelectButton *button)
gimp_font_select_button_init (GimpFontSelectButton *font_button)
{
GimpFontSelectButtonPrivate *priv;
priv = GIMP_FONT_SELECT_BUTTON_GET_PRIVATE (font_button);
button->priv = G_TYPE_INSTANCE_GET_PRIVATE (button,
GIMP_TYPE_FONT_SELECT_BUTTON,
GimpFontSelectButtonPrivate);
priv->font_name = NULL;
priv = GIMP_FONT_SELECT_BUTTON_GET_PRIVATE (button);
priv->title = g_strdup(_("Font Selection"));
priv->font_name = g_strdup(_("Sans"));
priv->temp_font_callback = NULL;
priv->inside = gimp_font_select_button_create_inside (button);
gtk_container_add (GTK_CONTAINER (button), priv->inside);
gtk_drag_dest_set (GTK_WIDGET (button),
GTK_DEST_DEFAULT_HIGHLIGHT |
GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_DROP,
&target, 1,
GDK_ACTION_COPY);
priv->inside = gimp_font_select_button_create_inside (font_button);
gtk_container_add (GTK_CONTAINER (font_button), priv->inside);
}
/**
* gimp_font_select_button_new:
* @title: Title of the dialog to use or %NULL means to use the default
* title.
* @title: Title of the dialog to use or %NULL to use the default title.
* @font_name: Initial font name.
*
* Creates a new #GtkWidget that completely controls the selection of
@ -199,115 +193,114 @@ gimp_font_select_button_init (GimpFontSelectButton *button)
* plug-in dialog.
*
* Returns: A #GtkWidget that you can use in your UI.
*
* Since: GIMP 2.4
*/
GtkWidget *
gimp_font_select_button_new (const gchar *title,
const gchar *font_name)
{
GtkWidget *button;
GtkWidget *font_button;
if (title)
button = g_object_new (GIMP_TYPE_FONT_SELECT_BUTTON,
"title", title,
"font-name", font_name,
NULL);
font_button = g_object_new (GIMP_TYPE_FONT_SELECT_BUTTON,
"title", title,
"font-name", font_name,
NULL);
else
button = g_object_new (GIMP_TYPE_FONT_SELECT_BUTTON,
"font-name", font_name,
NULL);
font_button = g_object_new (GIMP_TYPE_FONT_SELECT_BUTTON,
"font-name", font_name,
NULL);
return button;
}
/**
* gimp_font_select_button_close_popup:
* @button: A #GimpFontSelectButton
*
* Closes the popup window associated with @button.
*/
void
gimp_font_select_button_close_popup (GimpFontSelectButton *button)
{
GimpFontSelectButtonPrivate *priv;
g_return_if_fail (GIMP_IS_FONT_SELECT_BUTTON (button));
priv = GIMP_FONT_SELECT_BUTTON_GET_PRIVATE (button);
if (priv->temp_font_callback)
{
gimp_font_select_destroy (priv->temp_font_callback);
priv->temp_font_callback = NULL;
}
return font_button;
}
/**
* gimp_font_select_button_get_font_name:
* @button: A #GimpFontSelectButton
* @font_button: A #GimpFontSelectButton
*
* Retrieves the name of currently selected font.
*
* Returns: an internal copy of the font name which must not be freed.
*
* Since: 2.4
* Since: GIMP 2.4
*/
G_CONST_RETURN gchar *
gimp_font_select_button_get_font_name (GimpFontSelectButton *button)
gimp_font_select_button_get_font_name (GimpFontSelectButton *font_button)
{
g_return_val_if_fail (GIMP_IS_FONT_SELECT_BUTTON (button), NULL);
GimpFontSelectButtonPrivate *priv;
return GIMP_FONT_SELECT_BUTTON_GET_PRIVATE (button)->font_name;
g_return_val_if_fail (GIMP_IS_FONT_SELECT_BUTTON (font_button), NULL);
priv = GIMP_FONT_SELECT_BUTTON_GET_PRIVATE (font_button);
return priv->font_name;
}
/**
* gimp_font_select_button_set_font_name:
* @button: A #GimpFontSelectButton
* @font_button: A #GimpFontSelectButton
* @font_name: Font name to set; %NULL means no change.
*
* Sets the current font for the font select button.
*
* Since: 2.4
* Since: GIMP 2.4
*/
void
gimp_font_select_button_set_font_name (GimpFontSelectButton *button,
gimp_font_select_button_set_font_name (GimpFontSelectButton *font_button,
const gchar *font_name)
{
GimpFontSelectButtonPrivate *priv;
GimpSelectButton *select_button;
g_return_if_fail (GIMP_IS_FONT_SELECT_BUTTON (button));
g_return_if_fail (GIMP_IS_FONT_SELECT_BUTTON (font_button));
priv = GIMP_FONT_SELECT_BUTTON_GET_PRIVATE (button);
select_button = GIMP_SELECT_BUTTON (font_button);
if (priv->temp_font_callback)
gimp_fonts_set_popup (priv->temp_font_callback, font_name);
if (select_button->temp_callback)
gimp_fonts_set_popup (select_button->temp_callback, font_name);
else
gimp_font_select_button_callback (font_name, FALSE, button);
gimp_font_select_button_callback (font_name, FALSE, font_button);
}
/* private functions */
static void
gimp_font_select_button_finalize (GObject *object)
{
GimpFontSelectButtonPrivate *priv;
priv = GIMP_FONT_SELECT_BUTTON_GET_PRIVATE (object);
g_free (priv->font_name);
priv->font_name = NULL;
g_free (priv->title);
priv->title = NULL;
G_OBJECT_CLASS (gimp_font_select_button_parent_class)->finalize (object);
}
static void
gimp_font_select_button_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpFontSelectButtonPrivate *priv = GIMP_FONT_SELECT_BUTTON_GET_PRIVATE (object);
GimpFontSelectButton *font_button;
GimpFontSelectButtonPrivate *priv;
font_button = GIMP_FONT_SELECT_BUTTON (object);
priv = GIMP_FONT_SELECT_BUTTON_GET_PRIVATE (font_button);
switch (property_id)
{
case PROP_TITLE:
g_free (priv->title);
priv->title = g_value_dup_string (value);
g_object_notify (object, "title");
break;
case PROP_FONT_NAME:
gimp_font_select_button_set_font_name (GIMP_FONT_SELECT_BUTTON (object),
gimp_font_select_button_set_font_name (font_button,
g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@ -320,18 +313,20 @@ gimp_font_select_button_get_property (GObject *object,
GValue *value,
GParamSpec *pspec)
{
GimpFontSelectButtonPrivate *priv = GIMP_FONT_SELECT_BUTTON_GET_PRIVATE (object);
GimpFontSelectButton *font_button;
GimpFontSelectButtonPrivate *priv;
font_button = GIMP_FONT_SELECT_BUTTON (object);
priv = GIMP_FONT_SELECT_BUTTON_GET_PRIVATE (font_button);
switch (property_id)
{
case PROP_TITLE:
g_value_set_string (value, priv->title);
break;
case PROP_FONT_NAME:
g_value_set_string (value, priv->font_name);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@ -339,72 +334,64 @@ gimp_font_select_button_get_property (GObject *object,
}
static void
gimp_font_select_button_callback (const gchar *name,
gboolean closing,
gpointer data)
gimp_font_select_button_callback (const gchar *font_name,
gboolean dialog_closing,
gpointer user_data)
{
GimpFontSelectButton *button = GIMP_FONT_SELECT_BUTTON (data);
GimpFontSelectButtonPrivate *priv = GIMP_FONT_SELECT_BUTTON_GET_PRIVATE (button);
GimpFontSelectButton *font_button;
GimpFontSelectButtonPrivate *priv;
GimpSelectButton *select_button;
font_button = GIMP_FONT_SELECT_BUTTON (user_data);
priv = GIMP_FONT_SELECT_BUTTON_GET_PRIVATE (font_button);
select_button = GIMP_SELECT_BUTTON (font_button);
g_free (priv->font_name);
priv->font_name = g_strdup (name);
priv->font_name = g_strdup (font_name);
gtk_label_set_text (GTK_LABEL (priv->label), name);
gtk_label_set_text (GTK_LABEL (priv->label), font_name);
if (closing)
priv->temp_font_callback = NULL;
if (dialog_closing)
select_button->temp_callback = NULL;
g_signal_emit (button, font_button_signals[FONT_SET], 0, name, closing);
g_object_notify (G_OBJECT (button), "font-name");
g_signal_emit (font_button, font_button_signals[FONT_SET], 0,
font_name, dialog_closing);
g_object_notify (G_OBJECT (font_button), "font-name");
}
static void
gimp_font_select_button_clicked (GtkButton *button)
gimp_font_select_button_clicked (GimpFontSelectButton *font_button)
{
GimpFontSelectButtonPrivate *priv = GIMP_FONT_SELECT_BUTTON_GET_PRIVATE (button);
GimpFontSelectButtonPrivate *priv;
GimpSelectButton *select_button;
priv = GIMP_FONT_SELECT_BUTTON_GET_PRIVATE (font_button);
select_button = GIMP_SELECT_BUTTON (font_button);
if (priv->temp_font_callback)
if (select_button->temp_callback)
{
/* calling gimp_fonts_set_popup() raises the dialog */
gimp_fonts_set_popup (priv->temp_font_callback, priv->font_name);
gimp_fonts_set_popup (select_button->temp_callback,
priv->font_name);
}
else
{
priv->temp_font_callback =
select_button->temp_callback =
gimp_font_select_new (priv->title, priv->font_name,
gimp_font_select_button_callback,
button);
font_button);
}
}
static void
gimp_font_select_button_destroy (GtkObject *object)
{
GimpFontSelectButtonPrivate *priv = GIMP_FONT_SELECT_BUTTON_GET_PRIVATE (object);
if (priv->temp_font_callback)
{
gimp_font_select_destroy (priv->temp_font_callback);
priv->temp_font_callback = NULL;
}
g_free (priv->title);
priv->title = NULL;
g_free (priv->font_name);
priv->font_name = NULL;
GTK_OBJECT_CLASS (gimp_font_select_button_parent_class)->destroy (object);
}
static void
gimp_font_select_drag_data_received (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time)
gimp_font_select_drag_data_received (GimpFontSelectButton *font_button,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time)
{
gchar *str;
@ -427,8 +414,7 @@ gimp_font_select_drag_data_received (GtkWidget *widget,
{
gchar *name = str + name_offset;
gimp_font_select_button_set_font_name (GIMP_FONT_SELECT_BUTTON (widget),
name);
gimp_font_select_button_set_font_name (font_button, name);
}
}
@ -436,15 +422,21 @@ gimp_font_select_drag_data_received (GtkWidget *widget,
}
static GtkWidget *
gimp_font_select_button_create_inside (GimpFontSelectButton *button)
gimp_font_select_button_create_inside (GimpFontSelectButton *font_button)
{
GimpFontSelectButtonPrivate *priv = GIMP_FONT_SELECT_BUTTON_GET_PRIVATE (button);
GtkWidget *hbox;
GtkWidget *image;
GtkWidget *button;
GtkWidget *hbox;
GtkWidget *image;
GimpFontSelectButtonPrivate *priv;
priv = GIMP_FONT_SELECT_BUTTON_GET_PRIVATE (font_button);
gtk_widget_push_composite_child ();
button = gtk_button_new ();
hbox = gtk_hbox_new (FALSE, 4);
gtk_container_add (GTK_CONTAINER (button), hbox);
image = gtk_image_new_from_stock (GIMP_STOCK_FONT, GTK_ICON_SIZE_BUTTON);
gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
@ -452,9 +444,24 @@ gimp_font_select_button_create_inside (GimpFontSelectButton *button)
priv->label = gtk_label_new (priv->font_name);
gtk_box_pack_start (GTK_BOX (hbox), priv->label, TRUE, TRUE, 4);
gtk_widget_show_all (hbox);
gtk_widget_show_all (button);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gimp_font_select_button_clicked),
font_button);
gtk_drag_dest_set (GTK_WIDGET (button),
GTK_DEST_DEFAULT_HIGHLIGHT |
GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_DROP,
&target, 1,
GDK_ACTION_COPY);
g_signal_connect_swapped (button, "drag-data-received",
G_CALLBACK (gimp_font_select_drag_data_received),
font_button);
gtk_widget_pop_composite_child ();
return hbox;
return button;
}

View File

@ -22,6 +22,8 @@
#ifndef __GIMP_FONT_SELECT_BUTTON_H__
#define __GIMP_FONT_SELECT_BUTTON_H__
#include <libgimp/gimpselectbutton.h>
G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
@ -39,15 +41,12 @@ typedef struct _GimpFontSelectButtonClass GimpFontSelectButtonClass;
struct _GimpFontSelectButton
{
GtkButton parent_instance;
/*< private >*/
gpointer priv;
GimpSelectButton parent_instance;
};
struct _GimpFontSelectButtonClass
{
GtkButtonClass parent_class;
GimpSelectButtonClass parent_class;
/* font_set signal is emitted when font is chosen */
void (* font_set) (GimpFontSelectButton *font_button,
@ -64,15 +63,15 @@ struct _GimpFontSelectButtonClass
GType gimp_font_select_button_get_type (void) G_GNUC_CONST;
GtkWidget * gimp_font_select_button_new (const gchar *title,
GtkWidget * gimp_font_select_button_new (const gchar *title,
const gchar *font_name);
G_CONST_RETURN gchar * gimp_font_select_button_get_font_name
(GimpFontSelectButton *button);
void gimp_font_select_button_set_font_name
(GimpFontSelectButton *button,
const gchar *font_name);
void gimp_font_select_button_close_popup (GimpFontSelectButton *button);
G_CONST_RETURN gchar * gimp_font_select_button_get_font_name (GimpFontSelectButton *button);
void gimp_font_select_button_set_font_name (GimpFontSelectButton *button,
const gchar *font_name);
G_END_DECLS

View File

@ -22,84 +22,46 @@
#include "config.h"
#include <string.h>
#include "gimp.h"
#include "gimpui.h"
#include "libgimp-intl.h"
#include "gimpuitypes.h"
#include "gimpgradientselectbutton.h"
#undef GIMP_DISABLE_DEPRECATED
#include "gimpgradientmenu.h"
#define GRADIENT_SELECT_DATA_KEY "gimp-gradient-select-data"
#define CELL_HEIGHT 18
#define CELL_WIDTH 84
typedef struct _CompatCallbackData CompatCallbackData;
typedef struct _GradientSelect GradientSelect;
struct _GradientSelect
struct _CompatCallbackData
{
gchar *title;
GimpRunGradientCallback callback;
gpointer data;
GtkWidget *preview;
GtkWidget *button;
gchar *gradient_name; /* Local copy */
gint sample_size;
gboolean reverse;
gint n_samples;
gdouble *gradient_data; /* Local copy */
const gchar *temp_gradient_callback;
GimpRunGradientCallback callback;
gpointer data;
};
/* local function prototypes */
static void gimp_gradient_select_widget_callback (const gchar *name,
gint n_samples,
const gdouble *gradient_data,
gboolean closing,
gpointer data);
static void gimp_gradient_select_widget_clicked (GtkWidget *widget,
GradientSelect *gradient_sel);
static void gimp_gradient_select_widget_destroy (GtkWidget *widget,
GradientSelect *gradient_sel);
static void gimp_gradient_select_preview_size_allocate
(GtkWidget *widget,
GtkAllocation *allocation,
GradientSelect *gradient_sel);
static void gimp_gradient_select_preview_expose (GtkWidget *preview,
GdkEventExpose *event,
GradientSelect *gradient_sel);
static void gimp_gradient_select_drag_data_received (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time);
static const GtkTargetEntry target = { "application/x-gimp-gradient-name", 0 };
static void compat_callback (GimpGradientSelectButton *gradient_button,
const gchar *gradient_name,
gint width,
const gdouble *grad_data,
gboolean dialog_closing,
gpointer data);
/**
* gimp_gradient_select_widget_new:
* @title: Title of the dialog to use or %NULL to use the default title.
* @gradient_name: Initial gradient name or %NULL to use current selection.
* @gradient_name: Initial gradient name.
* @callback: A function to call when the selected gradient changes.
* @data: A pointer to arbitary data to be used in the call to
* @callback.
* @data: A pointer to arbitary data to be used in the call to @callback.
*
* 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.
*
* Since: GIMP 2.2
*/
GtkWidget *
gimp_gradient_select_widget_new (const gchar *title,
@ -107,70 +69,26 @@ gimp_gradient_select_widget_new (const gchar *title,
GimpRunGradientCallback callback,
gpointer data)
{
GradientSelect *gradient_sel;
GtkWidget *gradient_button;
CompatCallbackData *compat_data;
g_return_val_if_fail (callback != NULL, NULL);
if (! title)
title = _("Gradient Selection");
gradient_button = gimp_gradient_select_button_new (title, gradient_name);
gradient_sel = g_new0 (GradientSelect, 1);
compat_data = g_new (CompatCallbackData, 1);
compat_data->callback = callback;
compat_data->data = data;
gradient_sel->title = g_strdup (title);
gradient_sel->callback = callback;
gradient_sel->data = data;
g_signal_connect_data (gradient_button, "gradient-set",
G_CALLBACK (compat_callback),
compat_data, (GClosureNotify) g_free, 0);
gradient_sel->sample_size = CELL_WIDTH;
gradient_sel->reverse = FALSE;
if (! gradient_name || ! strlen (gradient_name))
gradient_sel->gradient_name = gimp_context_get_gradient ();
else
gradient_sel->gradient_name = g_strdup (gradient_name);
gradient_sel->button = gtk_button_new ();
g_signal_connect (gradient_sel->button, "clicked",
G_CALLBACK (gimp_gradient_select_widget_clicked),
gradient_sel);
g_signal_connect (gradient_sel->button, "destroy",
G_CALLBACK (gimp_gradient_select_widget_destroy),
gradient_sel);
gtk_drag_dest_set (GTK_WIDGET (gradient_sel->button),
GTK_DEST_DEFAULT_HIGHLIGHT |
GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_DROP,
&target, 1,
GDK_ACTION_COPY);
g_signal_connect (gradient_sel->button, "drag-data-received",
G_CALLBACK (gimp_gradient_select_drag_data_received),
NULL);
gradient_sel->preview = gtk_drawing_area_new ();
gtk_widget_set_size_request (gradient_sel->preview, CELL_WIDTH, CELL_HEIGHT);
gtk_container_add (GTK_CONTAINER (gradient_sel->button),
gradient_sel->preview);
gtk_widget_show (gradient_sel->preview);
g_signal_connect (gradient_sel->preview, "size-allocate",
G_CALLBACK (gimp_gradient_select_preview_size_allocate),
gradient_sel);
g_signal_connect (gradient_sel->preview, "expose-event",
G_CALLBACK (gimp_gradient_select_preview_expose),
gradient_sel);
g_object_set_data (G_OBJECT (gradient_sel->button),
GRADIENT_SELECT_DATA_KEY, gradient_sel);
return gradient_sel->button;
return gradient_button;
}
/**
* gimp_gradient_select_widget_close;
* gimp_gradient_select_widget_close:
* @widget: A gradient select widget.
*
* Closes the popup window associated with @widget.
@ -178,266 +96,40 @@ gimp_gradient_select_widget_new (const gchar *title,
void
gimp_gradient_select_widget_close (GtkWidget *widget)
{
GradientSelect *gradient_sel;
g_return_if_fail (widget != NULL);
gradient_sel = g_object_get_data (G_OBJECT (widget),
GRADIENT_SELECT_DATA_KEY);
g_return_if_fail (gradient_sel != NULL);
if (gradient_sel->temp_gradient_callback)
{
gimp_gradient_select_destroy (gradient_sel->temp_gradient_callback);
gradient_sel->temp_gradient_callback = NULL;
}
gimp_select_button_close_popup (GIMP_SELECT_BUTTON (widget));
}
/**
* gimp_gradient_select_widget_set:
* gimp_gradient_select_widget_set;
* @widget: A gradient select widget.
* @gradient_name: 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
* 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_new().
*/
void
gimp_gradient_select_widget_set (GtkWidget *widget,
const gchar *gradient_name)
{
GradientSelect *gradient_sel;
g_return_if_fail (widget != NULL);
gradient_sel = g_object_get_data (G_OBJECT (widget),
GRADIENT_SELECT_DATA_KEY);
g_return_if_fail (gradient_sel != NULL);
if (gradient_sel->temp_gradient_callback)
{
gimp_gradients_set_popup (gradient_sel->temp_gradient_callback,
gradient_name);
}
else
{
gchar *name;
gdouble *samples;
gint n_samples;
if (! gradient_name || ! strlen (gradient_name))
name = gimp_context_get_gradient ();
else
name = g_strdup (gradient_name);
if (gimp_gradient_get_uniform_samples (name,
gradient_sel->sample_size,
gradient_sel->reverse,
&n_samples,
&samples))
{
gimp_gradient_select_widget_callback (name,
n_samples, samples,
FALSE, gradient_sel);
g_free (samples);
}
g_free (name);
}
}
/* private functions */
static void
gimp_gradient_select_widget_callback (const gchar *name,
gint n_samples,
const gdouble *gradient_data,
gboolean closing,
gpointer data)
{
GradientSelect *gradient_sel = data;
g_free (gradient_sel->gradient_name);
g_free (gradient_sel->gradient_data);
gradient_sel->gradient_name = g_strdup (name);
gradient_sel->n_samples = n_samples;
gradient_sel->gradient_data = g_memdup (gradient_data,
n_samples * sizeof (gdouble));
gtk_widget_queue_draw (gradient_sel->preview);
if (gradient_sel->callback)
gradient_sel->callback (name,
n_samples, gradient_data, closing,
gradient_sel->data);
if (closing)
gradient_sel->temp_gradient_callback = NULL;
gimp_gradient_select_button_set_gradient_name
(GIMP_GRADIENT_SELECT_BUTTON (widget), gradient_name);
}
static void
gimp_gradient_select_widget_clicked (GtkWidget *widget,
GradientSelect *gradient_sel)
compat_callback (GimpGradientSelectButton *gradient_button,
const gchar *gradient_name,
gint width,
const gdouble *grad_data,
gboolean dialog_closing,
gpointer data)
{
if (gradient_sel->temp_gradient_callback)
{
/* calling gimp_gradients_set_popup() raises the dialog */
gimp_gradients_set_popup (gradient_sel->temp_gradient_callback,
gradient_sel->gradient_name);
}
else
{
gradient_sel->temp_gradient_callback =
gimp_gradient_select_new (gradient_sel->title,
gradient_sel->gradient_name,
gradient_sel->sample_size,
gimp_gradient_select_widget_callback,
gradient_sel);
}
}
static void
gimp_gradient_select_widget_destroy (GtkWidget *widget,
GradientSelect *gradient_sel)
{
if (gradient_sel->temp_gradient_callback)
{
gimp_gradient_select_destroy (gradient_sel->temp_gradient_callback);
gradient_sel->temp_gradient_callback = NULL;
}
g_free (gradient_sel->title);
g_free (gradient_sel->gradient_name);
g_free (gradient_sel->gradient_data);
g_free (gradient_sel);
}
static void
gimp_gradient_select_preview_size_allocate (GtkWidget *widget,
GtkAllocation *allocation,
GradientSelect *gradient_sel)
{
gdouble *samples;
gint n_samples;
if (gimp_gradient_get_uniform_samples (gradient_sel->gradient_name,
allocation->width,
gradient_sel->reverse,
&n_samples,
&samples))
{
g_free (gradient_sel->gradient_data);
gradient_sel->sample_size = allocation->width;
gradient_sel->n_samples = n_samples;
gradient_sel->gradient_data = samples;
}
}
static void
gimp_gradient_select_preview_expose (GtkWidget *widget,
GdkEventExpose *event,
GradientSelect *gradient_sel)
{
const gdouble *src;
guchar *p0;
guchar *p1;
guchar *even;
guchar *odd;
gint width;
gint x, y;
src = gradient_sel->gradient_data;
if (! src)
return;
width = gradient_sel->n_samples / 4;
p0 = even = g_malloc (width * 3);
p1 = odd = g_malloc (width * 3);
for (x = 0; x < width; x++)
{
gdouble r, g, b, a;
gdouble c0, c1;
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 = event->area.y; y < event->area.y + event->area.height; y++)
{
guchar *buf = ((y / GIMP_CHECK_SIZE_SM) & 1) ? odd : even;
gdk_draw_rgb_image_dithalign (widget->window,
widget->style->fg_gc[widget->state],
event->area.x, y,
event->area.width, 1,
GDK_RGB_DITHER_MAX,
buf + event->area.x * 3,
width * 3,
- event->area.x, - y);
}
g_free (odd);
g_free (even);
}
static void
gimp_gradient_select_drag_data_received (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time)
{
gchar *str;
if ((selection->format != 8) || (selection->length < 1))
{
g_warning ("Received invalid gradient data!");
return;
}
str = g_strndup ((const gchar *) selection->data, selection->length);
if (g_utf8_validate (str, -1, NULL))
{
gint pid;
gpointer unused;
gint name_offset = 0;
if (sscanf (str, "%i:%p:%n", &pid, &unused, &name_offset) >= 2 &&
pid == gimp_getpid () && name_offset > 0)
{
gchar *name = str + name_offset;
gimp_gradient_select_widget_set (widget, name);
}
}
g_free (str);
CompatCallbackData *compat_data = data;
compat_data->callback (gradient_name, width, grad_data, dialog_closing,
compat_data->data);
}

View File

@ -22,6 +22,12 @@
#ifndef __GIMP_GRAIDENT_MENU_H__
#define __GIMP_GRADIENT_MENU_H__
/* These functions are deprecated and should not be used in newly
* written code.
*/
#ifndef GIMP_DISABLE_DEPRECATED
G_BEGIN_DECLS
@ -37,4 +43,6 @@ void gimp_gradient_select_widget_set (GtkWidget *widget,
G_END_DECLS
#endif /* GIMP_DISABLE_DEPRECATED */
#endif /* __GIMP_GRADIENT_MENU_H__ */

View File

@ -0,0 +1,628 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimpgradientselectbutton.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 <gtk/gtk.h>
#include "libgimpwidgets/gimpwidgets.h"
#include "gimp.h"
#include "gimpuitypes.h"
#include "gimpgradientselectbutton.h"
#include "gimpuimarshal.h"
#include "libgimp-intl.h"
#define CELL_HEIGHT 18
#define CELL_WIDTH 84
#define GIMP_GRADIENT_SELECT_BUTTON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GIMP_TYPE_GRADIENT_SELECT_BUTTON, GimpGradientSelectButtonPrivate))
typedef struct _GimpGradientSelectButtonPrivate GimpGradientSelectButtonPrivate;
struct _GimpGradientSelectButtonPrivate
{
gchar *title;
gchar *gradient_name; /* Local copy */
gint sample_size;
gboolean reverse;
gint n_samples;
gdouble *gradient_data; /* Local copy */
GtkWidget *inside;
GtkWidget *preview;
};
enum
{
GRADIENT_SET,
LAST_SIGNAL
};
enum
{
PROP_0,
PROP_TITLE,
PROP_GRADIENT_NAME
};
/* local function prototypes */
static void gimp_gradient_select_button_finalize (GObject *object);
static void gimp_gradient_select_button_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_gradient_select_button_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_gradient_select_button_clicked (GimpGradientSelectButton *gradient_button);
static void gimp_gradient_select_button_callback (const gchar *gradient_name,
gint n_samples,
const gdouble *gradient_data,
gboolean dialog_closing,
gpointer user_data);
static void gimp_gradient_select_preview_size_allocate
(GtkWidget *widget,
GtkAllocation *allocation,
GimpGradientSelectButton *gradient_button);
static void gimp_gradient_select_preview_expose (GtkWidget *preview,
GdkEventExpose *event,
GimpGradientSelectButton *gradient_button);
static void gimp_gradient_select_drag_data_received (GimpGradientSelectButton *gradient_button,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time);
static GtkWidget * gimp_gradient_select_button_create_inside (GimpGradientSelectButton *gradient_button);
static const GtkTargetEntry target = { "application/x-gimp-gradient-name", 0 };
static guint gradient_button_signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (GimpGradientSelectButton, gimp_gradient_select_button,
GIMP_TYPE_SELECT_BUTTON)
static void
gimp_gradient_select_button_class_init (GimpGradientSelectButtonClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpSelectButtonClass *select_button_class = GIMP_SELECT_BUTTON_CLASS (klass);
object_class->finalize = gimp_gradient_select_button_finalize;
object_class->set_property = gimp_gradient_select_button_set_property;
object_class->get_property = gimp_gradient_select_button_get_property;
select_button_class->select_destroy = gimp_gradient_select_destroy;
klass->gradient_set = NULL;
/**
* GimpGradientSelectButton:title:
*
* The title to be used for the gradient selection popup dialog.
*
* Since: GIMP 2.4
*/
g_object_class_install_property (object_class, PROP_TITLE,
g_param_spec_string ("title",
"Title",
"The title to be used for the gradient selection popup dialog",
_("Gradient Selection"),
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
/**
* GimpGradientSelectButton:gradient-name:
*
* The name of the currently selected gradient.
*
* Since: GIMP 2.4
*/
g_object_class_install_property (object_class, PROP_GRADIENT_NAME,
g_param_spec_string ("gradient-name",
"Gradient name",
"The name of the currently selected gradient",
NULL,
GIMP_PARAM_READWRITE));
/**
* GimpGradientSelectButton::gradient-set:
* @widget: the object which received the signal.
* @gradient_name: the name of the currently selected gradient.
* @width: width of the gradient
* @grad_data: gradient data
* @dialog_closing: whether the dialog was closed or not.
*
* The ::gradient-set signal is emitted when the user selects a gradient.
*
* Since: GIMP 2.4
*/
gradient_button_signals[GRADIENT_SET] =
g_signal_new ("gradient-set",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpGradientSelectButtonClass, gradient_set),
NULL, NULL,
_gimpui_marshal_VOID__STRING_INT_POINTER_BOOLEAN,
G_TYPE_NONE, 4,
G_TYPE_STRING,
G_TYPE_INT,
G_TYPE_POINTER,
G_TYPE_BOOLEAN);
g_type_class_add_private (object_class,
sizeof (GimpGradientSelectButtonPrivate));
}
static void
gimp_gradient_select_button_init (GimpGradientSelectButton *gradient_button)
{
GimpGradientSelectButtonPrivate *priv;
priv = GIMP_GRADIENT_SELECT_BUTTON_GET_PRIVATE (gradient_button);
priv->gradient_name = gimp_context_get_gradient ();
priv->sample_size = CELL_WIDTH;
priv->reverse = FALSE;
priv->inside = gimp_gradient_select_button_create_inside (gradient_button);
gtk_container_add (GTK_CONTAINER (gradient_button), priv->inside);
}
/**
* gimp_gradient_select_button_new:
* @title: Title of the dialog to use or %NULL to use the default title.
* @gradient_name: Initial gradient name.
*
* 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.
*
* Since: GIMP 2.4
*/
GtkWidget *
gimp_gradient_select_button_new (const gchar *title,
const gchar *gradient_name)
{
GtkWidget *gradient_button;
if (title)
gradient_button = g_object_new (GIMP_TYPE_GRADIENT_SELECT_BUTTON,
"title", title,
"gradient-name", gradient_name,
NULL);
else
gradient_button = g_object_new (GIMP_TYPE_GRADIENT_SELECT_BUTTON,
"gradient-name", gradient_name,
NULL);
return gradient_button;
}
/**
* gimp_gradient_select_button_get_gradient_name:
* @gradient_button: A #GimpGradientSelectButton
*
* Retrieves the name of currently selected gradient.
*
* Returns: an internal copy of the gradient name which must not be freed.
*
* Since: GIMP 2.4
*/
G_CONST_RETURN gchar *
gimp_gradient_select_button_get_gradient_name (GimpGradientSelectButton *gradient_button)
{
GimpGradientSelectButtonPrivate *priv;
g_return_val_if_fail (GIMP_IS_GRADIENT_SELECT_BUTTON (gradient_button), NULL);
priv = GIMP_GRADIENT_SELECT_BUTTON_GET_PRIVATE (gradient_button);
return priv->gradient_name;
}
/**
* gimp_gradient_select_button_set_gradient_name:
* @gradient_button: A #GimpGradientSelectButton
* @gradient_name: Gradient name to set.
*
* Sets the current gradient for the gradient select button.
*
* Since: GIMP 2.4
*/
void
gimp_gradient_select_button_set_gradient_name (GimpGradientSelectButton *gradient_button,
const gchar *gradient_name)
{
GimpGradientSelectButtonPrivate *priv;
GimpSelectButton *select_button;
g_return_if_fail (GIMP_IS_GRADIENT_SELECT_BUTTON (gradient_button));
priv = GIMP_GRADIENT_SELECT_BUTTON_GET_PRIVATE (gradient_button);
select_button = GIMP_SELECT_BUTTON (gradient_button);
if (select_button->temp_callback)
{
gimp_gradients_set_popup (select_button->temp_callback, gradient_name);
}
else
{
gchar *name;
gdouble *samples;
gint n_samples;
if (gradient_name && *gradient_name)
name = g_strdup (gradient_name);
else
name = gimp_context_get_gradient ();
if (gimp_gradient_get_uniform_samples (name,
priv->sample_size,
priv->reverse,
&n_samples,
&samples))
{
gimp_gradient_select_button_callback (name,
n_samples, samples,
FALSE, gradient_button);
g_free (samples);
}
g_free (name);
}
}
/* private functions */
static void
gimp_gradient_select_button_finalize (GObject *object)
{
GimpGradientSelectButtonPrivate *priv;
priv = GIMP_GRADIENT_SELECT_BUTTON_GET_PRIVATE (object);
g_free (priv->gradient_name);
priv->gradient_name = NULL;
g_free (priv->gradient_data);
priv->gradient_data = NULL;
g_free (priv->title);
priv->title = NULL;
G_OBJECT_CLASS (gimp_gradient_select_button_parent_class)->finalize (object);
}
static void
gimp_gradient_select_button_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpGradientSelectButton *gradient_button;
GimpGradientSelectButtonPrivate *priv;
gradient_button = GIMP_GRADIENT_SELECT_BUTTON (object);
priv = GIMP_GRADIENT_SELECT_BUTTON_GET_PRIVATE (gradient_button);
switch (property_id)
{
case PROP_TITLE:
priv->title = g_value_dup_string (value);
break;
case PROP_GRADIENT_NAME:
gimp_gradient_select_button_set_gradient_name (gradient_button,
g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_gradient_select_button_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpGradientSelectButton *gradient_button;
GimpGradientSelectButtonPrivate *priv;
gradient_button = GIMP_GRADIENT_SELECT_BUTTON (object);
priv = GIMP_GRADIENT_SELECT_BUTTON_GET_PRIVATE (gradient_button);
switch (property_id)
{
case PROP_TITLE:
g_value_set_string (value, priv->title);
break;
case PROP_GRADIENT_NAME:
g_value_set_string (value, priv->gradient_name);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_gradient_select_button_callback (const gchar *gradient_name,
gint n_samples,
const gdouble *gradient_data,
gboolean dialog_closing,
gpointer user_data)
{
GimpGradientSelectButton *gradient_button;
GimpGradientSelectButtonPrivate *priv;
GimpSelectButton *select_button;
gradient_button = GIMP_GRADIENT_SELECT_BUTTON (user_data);
priv = GIMP_GRADIENT_SELECT_BUTTON_GET_PRIVATE (gradient_button);
select_button = GIMP_SELECT_BUTTON (gradient_button);
g_free (priv->gradient_name);
g_free (priv->gradient_data);
priv->gradient_name = g_strdup (gradient_name);
priv->n_samples = n_samples;
priv->gradient_data = g_memdup (gradient_data, n_samples * sizeof (gdouble));
gtk_widget_queue_draw (priv->preview);
if (dialog_closing)
select_button->temp_callback = NULL;
g_signal_emit (gradient_button, gradient_button_signals[GRADIENT_SET], 0,
gradient_name, n_samples, gradient_data, dialog_closing);
g_object_notify (G_OBJECT (gradient_button), "gradient-name");
}
static void
gimp_gradient_select_button_clicked (GimpGradientSelectButton *gradient_button)
{
GimpGradientSelectButtonPrivate *priv;
GimpSelectButton *select_button;
priv = GIMP_GRADIENT_SELECT_BUTTON_GET_PRIVATE (gradient_button);
select_button = GIMP_SELECT_BUTTON (gradient_button);
if (select_button->temp_callback)
{
/* calling gimp_gradients_set_popup() raises the dialog */
gimp_gradients_set_popup (select_button->temp_callback,
priv->gradient_name);
}
else
{
select_button->temp_callback =
gimp_gradient_select_new (priv->title, priv->gradient_name,
priv->sample_size,
gimp_gradient_select_button_callback,
gradient_button);
}
}
static void
gimp_gradient_select_preview_size_allocate (GtkWidget *widget,
GtkAllocation *allocation,
GimpGradientSelectButton *gradient_button)
{
gdouble *samples;
gint n_samples;
GimpGradientSelectButtonPrivate *priv;
priv = GIMP_GRADIENT_SELECT_BUTTON_GET_PRIVATE (gradient_button);
if (gimp_gradient_get_uniform_samples (priv->gradient_name,
allocation->width,
priv->reverse,
&n_samples,
&samples))
{
g_free (priv->gradient_data);
priv->sample_size = allocation->width;
priv->n_samples = n_samples;
priv->gradient_data = samples;
}
}
static void
gimp_gradient_select_preview_expose (GtkWidget *widget,
GdkEventExpose *event,
GimpGradientSelectButton *gradient_button)
{
const gdouble *src;
guchar *p0;
guchar *p1;
guchar *even;
guchar *odd;
gint width;
gint x, y;
GimpGradientSelectButtonPrivate *priv;
priv = GIMP_GRADIENT_SELECT_BUTTON_GET_PRIVATE (gradient_button);
src = priv->gradient_data;
if (! src)
return;
width = priv->n_samples / 4;
p0 = even = g_malloc (width * 3);
p1 = odd = g_malloc (width * 3);
for (x = 0; x < width; x++)
{
gdouble r, g, b, a;
gdouble c0, c1;
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 = event->area.y; y < event->area.y + event->area.height; y++)
{
guchar *buf = ((y / GIMP_CHECK_SIZE_SM) & 1) ? odd : even;
gdk_draw_rgb_image_dithalign (widget->window,
widget->style->fg_gc[widget->state],
event->area.x, y,
event->area.width, 1,
GDK_RGB_DITHER_MAX,
buf + event->area.x * 3,
width * 3,
- event->area.x, - y);
}
g_free (odd);
g_free (even);
}
static void
gimp_gradient_select_drag_data_received (GimpGradientSelectButton *gradient_button,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time)
{
gchar *str;
if ((selection->format != 8) || (selection->length < 1))
{
g_warning ("Received invalid gradient data!");
return;
}
str = g_strndup ((const gchar *) selection->data, selection->length);
if (g_utf8_validate (str, -1, NULL))
{
gint pid;
gpointer unused;
gint name_offset = 0;
if (sscanf (str, "%i:%p:%n", &pid, &unused, &name_offset) >= 2 &&
pid == gimp_getpid () && name_offset > 0)
{
gchar *name = str + name_offset;
gimp_gradient_select_button_set_gradient_name (gradient_button, name);
}
}
g_free (str);
}
static GtkWidget *
gimp_gradient_select_button_create_inside (GimpGradientSelectButton *gradient_button)
{
GtkWidget *button;
GimpGradientSelectButtonPrivate *priv;
priv = GIMP_GRADIENT_SELECT_BUTTON_GET_PRIVATE (gradient_button);
gtk_widget_push_composite_child ();
button = gtk_button_new ();
priv->preview = gtk_drawing_area_new ();
gtk_widget_set_size_request (priv->preview, CELL_WIDTH, CELL_HEIGHT);
gtk_container_add (GTK_CONTAINER (button), priv->preview);
g_signal_connect (priv->preview, "size-allocate",
G_CALLBACK (gimp_gradient_select_preview_size_allocate),
gradient_button);
g_signal_connect (priv->preview, "expose-event",
G_CALLBACK (gimp_gradient_select_preview_expose),
gradient_button);
gtk_widget_show_all (button);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gimp_gradient_select_button_clicked),
gradient_button);
gtk_drag_dest_set (GTK_WIDGET (button),
GTK_DEST_DEFAULT_HIGHLIGHT |
GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_DROP,
&target, 1,
GDK_ACTION_COPY);
g_signal_connect_swapped (button, "drag-data-received",
G_CALLBACK (gimp_gradient_select_drag_data_received),
gradient_button);
gtk_widget_pop_composite_child ();
return button;
}

View File

@ -0,0 +1,78 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimpgradientselectbutton.h
*
* 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
* Lesser 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.
*/
#ifndef __GIMP_GRADIENT_SELECT_BUTTON_H__
#define __GIMP_GRADIENT_SELECT_BUTTON_H__
#include <libgimp/gimpselectbutton.h>
G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
#define GIMP_TYPE_GRADIENT_SELECT_BUTTON (gimp_gradient_select_button_get_type ())
#define GIMP_GRADIENT_SELECT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_GRADIENT_SELECT_BUTTON, GimpGradientSelectButton))
#define GIMP_GRADIENT_SELECT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_GRADIENT_SELECT_BUTTON, GimpGradientSelectButtonClass))
#define GIMP_IS_GRADIENT_SELECT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_GRADIENT_SELECT_BUTTON))
#define GIMP_IS_GRADIENT_SELECT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_GRADIENT_SELECT_BUTTON))
#define GIMP_GRADIENT_SELECT_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_GRADIENT_SELECT_BUTTON, GimpGradientSelectButtonClass))
typedef struct _GimpGradientSelectButtonClass GimpGradientSelectButtonClass;
struct _GimpGradientSelectButton
{
GimpSelectButton parent_instance;
};
struct _GimpGradientSelectButtonClass
{
GimpSelectButtonClass parent_class;
/* gradient_set signal is emitted when gradient is chosen */
void (* gradient_set) (GimpGradientSelectButton *gradient_button,
const gchar *gradient_name,
gint width,
const gdouble *gradient_data,
gboolean dialog_closing);
/* Padding for future expansion */
void (*_gimp_reserved1) (void);
void (*_gimp_reserved2) (void);
void (*_gimp_reserved3) (void);
void (*_gimp_reserved4) (void);
};
GType gimp_gradient_select_button_get_type (void) G_GNUC_CONST;
GtkWidget * gimp_gradient_select_button_new (const gchar *title,
const gchar *gradient_name);
G_CONST_RETURN gchar * gimp_gradient_select_button_get_gradient_name (GimpGradientSelectButton *button);
void gimp_gradient_select_button_set_gradient_name (GimpGradientSelectButton *button,
const gchar *gradient_name);
G_END_DECLS
#endif /* __GIMP_GRADIENT_SELECT_BUTTON_H__ */

View File

@ -23,57 +23,32 @@
#include "config.h"
#include "gimp.h"
#include "gimpui.h"
#include "libgimp-intl.h"
#include "gimpuitypes.h"
#include "gimppaletteselectbutton.h"
#undef GIMP_DISABLE_DEPRECATED
#include "gimppalettemenu.h"
#define PALETTE_SELECT_DATA_KEY "gimp-palette-selct-data"
typedef struct _CompatCallbackData CompatCallbackData;
typedef struct _PaletteSelect PaletteSelect;
struct _PaletteSelect
struct _CompatCallbackData
{
gchar *title;
GimpRunPaletteCallback callback;
gpointer data;
GtkWidget *button;
GtkWidget *label;
gchar *palette_name; /* Local copy */
const gchar *temp_palette_callback;
GimpRunPaletteCallback callback;
gpointer data;
};
/* local function prototypes */
static void gimp_palette_select_widget_callback (const gchar *name,
gboolean closing,
gpointer data);
static void gimp_palette_select_widget_clicked (GtkWidget *widget,
PaletteSelect *palette_sel);
static void gimp_palette_select_widget_destroy (GtkWidget *widget,
PaletteSelect *palette_sel);
static void gimp_palette_select_drag_data_received (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time);
static const GtkTargetEntry target = { "application/x-gimp-palette-name", 0 };
static void compat_callback (GimpPaletteSelectButton *palette_button,
const gchar *palette_name,
gboolean dialog_closing,
gpointer data);
/**
* gimp_palette_select_widget_new:
* @title: Title of the dialog to use or %NULL means to use the default
* title.
* @title: Title of the dialog to use or %NULL to use the default title.
* @palette_name: Initial palette name.
* @callback: A function to call when the selected palette changes.
* @data: A pointer to arbitary data to be used in the call to @callback.
@ -92,59 +67,22 @@ gimp_palette_select_widget_new (const gchar *title,
GimpRunPaletteCallback callback,
gpointer data)
{
PaletteSelect *palette_sel;
GtkWidget *hbox;
GtkWidget *image;
GtkWidget *palette_button;
CompatCallbackData *compat_data;
g_return_val_if_fail (callback != NULL, NULL);
if (! title)
title = _("Palette Selection");
palette_button = gimp_palette_select_button_new (title, palette_name);
palette_sel = g_new0 (PaletteSelect, 1);
compat_data = g_new (CompatCallbackData, 1);
compat_data->callback = callback;
compat_data->data = data;
palette_sel->title = g_strdup (title);
palette_sel->callback = callback;
palette_sel->data = data;
g_signal_connect_data (palette_button, "palette-set",
G_CALLBACK (compat_callback),
compat_data, (GClosureNotify) g_free, 0);
palette_sel->palette_name = g_strdup (palette_name);
palette_sel->button = gtk_button_new ();
g_signal_connect (palette_sel->button, "clicked",
G_CALLBACK (gimp_palette_select_widget_clicked),
palette_sel);
g_signal_connect (palette_sel->button, "destroy",
G_CALLBACK (gimp_palette_select_widget_destroy),
palette_sel);
gtk_drag_dest_set (GTK_WIDGET (palette_sel->button),
GTK_DEST_DEFAULT_HIGHLIGHT |
GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_DROP,
&target, 1,
GDK_ACTION_COPY);
g_signal_connect (palette_sel->button, "drag-data-received",
G_CALLBACK (gimp_palette_select_drag_data_received),
NULL);
hbox = gtk_hbox_new (FALSE, 4);
gtk_container_add (GTK_CONTAINER (palette_sel->button), hbox);
gtk_widget_show (hbox);
image = gtk_image_new_from_stock (GIMP_STOCK_PALETTE, GTK_ICON_SIZE_BUTTON);
gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
gtk_widget_show (image);
palette_sel->label = gtk_label_new (palette_name);
gtk_box_pack_start (GTK_BOX (hbox), palette_sel->label, TRUE, TRUE, 4);
gtk_widget_show (palette_sel->label);
g_object_set_data (G_OBJECT (palette_sel->button),
PALETTE_SELECT_DATA_KEY, palette_sel);
return palette_sel->button;
return palette_button;
}
/**
@ -158,17 +96,9 @@ gimp_palette_select_widget_new (const gchar *title,
void
gimp_palette_select_widget_close (GtkWidget *widget)
{
PaletteSelect *palette_sel;
g_return_if_fail (widget != NULL);
palette_sel = g_object_get_data (G_OBJECT (widget), PALETTE_SELECT_DATA_KEY);
g_return_if_fail (palette_sel != NULL);
if (palette_sel->temp_palette_callback)
{
gimp_palette_select_destroy (palette_sel->temp_palette_callback);
palette_sel->temp_palette_callback = NULL;
}
gimp_select_button_close_popup (GIMP_SELECT_BUTTON (widget));
}
/**
@ -186,108 +116,19 @@ void
gimp_palette_select_widget_set (GtkWidget *widget,
const gchar *palette_name)
{
PaletteSelect *palette_sel;
g_return_if_fail (widget != NULL);
palette_sel = g_object_get_data (G_OBJECT (widget), PALETTE_SELECT_DATA_KEY);
g_return_if_fail (palette_sel != NULL);
if (palette_sel->temp_palette_callback)
gimp_palettes_set_popup (palette_sel->temp_palette_callback, palette_name);
else
gimp_palette_select_widget_callback (palette_name, FALSE, palette_sel);
}
/* private functions */
static void
gimp_palette_select_widget_callback (const gchar *name,
gboolean closing,
gpointer data)
{
PaletteSelect *palette_sel = (PaletteSelect *) data;
g_free (palette_sel->palette_name);
palette_sel->palette_name = g_strdup (name);
gtk_label_set_text (GTK_LABEL (palette_sel->label), name);
if (palette_sel->callback)
palette_sel->callback (name, closing, palette_sel->data);
if (closing)
palette_sel->temp_palette_callback = NULL;
gimp_palette_select_button_set_palette_name
(GIMP_PALETTE_SELECT_BUTTON (widget), palette_name);
}
static void
gimp_palette_select_widget_clicked (GtkWidget *widget,
PaletteSelect *palette_sel)
compat_callback (GimpPaletteSelectButton *palette_button,
const gchar *palette_name,
gboolean dialog_closing,
gpointer data)
{
if (palette_sel->temp_palette_callback)
{
/* calling gimp_palettes_set_popup() raises the dialog */
gimp_palettes_set_popup (palette_sel->temp_palette_callback,
palette_sel->palette_name);
}
else
{
palette_sel->temp_palette_callback =
gimp_palette_select_new (palette_sel->title,
palette_sel->palette_name,
gimp_palette_select_widget_callback,
palette_sel);
}
}
static void
gimp_palette_select_widget_destroy (GtkWidget *widget,
PaletteSelect *palette_sel)
{
if (palette_sel->temp_palette_callback)
{
gimp_palette_select_destroy (palette_sel->temp_palette_callback);
palette_sel->temp_palette_callback = NULL;
}
g_free (palette_sel->title);
g_free (palette_sel->palette_name);
g_free (palette_sel);
}
static void
gimp_palette_select_drag_data_received (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time)
{
gchar *str;
if ((selection->format != 8) || (selection->length < 1))
{
g_warning ("Received invalid palette data!");
return;
}
str = g_strndup ((const gchar *) selection->data, selection->length);
if (g_utf8_validate (str, -1, NULL))
{
gint pid;
gpointer unused;
gint name_offset = 0;
if (sscanf (str, "%i:%p:%n", &pid, &unused, &name_offset) >= 2 &&
pid == gimp_getpid () && name_offset > 0)
{
gchar *name = str + name_offset;
gimp_palette_select_widget_set (widget, name);
}
}
g_free (str);
CompatCallbackData *compat_data = data;
compat_data->callback (palette_name, dialog_closing, compat_data->data);
}

View File

@ -22,6 +22,12 @@
#ifndef __GIMP_PALETTE_MENU_H__
#define __GIMP_PALETTE_MENU_H__
/* These functions are deprecated and should not be used in newly
* written code.
*/
#ifndef GIMP_DISABLE_DEPRECATED
G_BEGIN_DECLS
@ -37,4 +43,6 @@ void gimp_palette_select_widget_set (GtkWidget *widget,
G_END_DECLS
#endif /* GIMP_DISABLE_DEPRECATED */
#endif /* __GIMP_PALETTE_MENU_H__ */

View File

@ -0,0 +1,467 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimppaletteselectbutton.c
* Copyright (C) 2004 Michael Natterer <mitch@gimp.org>
*
* 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 <gtk/gtk.h>
#include "libgimpwidgets/gimpwidgets.h"
#include "gimp.h"
#include "gimpuitypes.h"
#include "gimppaletteselectbutton.h"
#include "gimpuimarshal.h"
#include "libgimp-intl.h"
#define GIMP_PALETTE_SELECT_BUTTON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GIMP_TYPE_PALETTE_SELECT_BUTTON, GimpPaletteSelectButtonPrivate))
typedef struct _GimpPaletteSelectButtonPrivate GimpPaletteSelectButtonPrivate;
struct _GimpPaletteSelectButtonPrivate
{
gchar *title;
gchar *palette_name; /* Local copy */
GtkWidget *inside;
GtkWidget *label;
};
enum
{
PALETTE_SET,
LAST_SIGNAL
};
enum
{
PROP_0,
PROP_TITLE,
PROP_PALETTE_NAME
};
/* local function prototypes */
static void gimp_palette_select_button_finalize (GObject *object);
static void gimp_palette_select_button_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_palette_select_button_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_palette_select_button_clicked (GimpPaletteSelectButton *palette_button);
static void gimp_palette_select_button_callback (const gchar *palette_name,
gboolean dialog_closing,
gpointer user_data);
static void gimp_palette_select_drag_data_received (GimpPaletteSelectButton *palette_button,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time);
static GtkWidget * gimp_palette_select_button_create_inside (GimpPaletteSelectButton *palette_button);
static const GtkTargetEntry target = { "application/x-gimp-palette-name", 0 };
static guint palette_button_signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (GimpPaletteSelectButton, gimp_palette_select_button,
GIMP_TYPE_SELECT_BUTTON)
static void
gimp_palette_select_button_class_init (GimpPaletteSelectButtonClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpSelectButtonClass *select_button_class = GIMP_SELECT_BUTTON_CLASS (klass);
object_class->finalize = gimp_palette_select_button_finalize;
object_class->set_property = gimp_palette_select_button_set_property;
object_class->get_property = gimp_palette_select_button_get_property;
select_button_class->select_destroy = gimp_palette_select_destroy;
klass->palette_set = NULL;
/**
* GimpPaletteSelectButton:title:
*
* The title to be used for the palette selection popup dialog.
*
* Since: GIMP 2.4
*/
g_object_class_install_property (object_class, PROP_TITLE,
g_param_spec_string ("title",
"Title",
"The title to be used for the palette selection popup dialog",
_("Palette Selection"),
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
/**
* GimpPaletteSelectButton:palette-name:
*
* The name of the currently selected palette.
*
* Since: GIMP 2.4
*/
g_object_class_install_property (object_class, PROP_PALETTE_NAME,
g_param_spec_string ("palette-name",
"Palette name",
"The name of the currently selected palette",
NULL,
GIMP_PARAM_READWRITE));
/**
* GimpPaletteSelectButton::palette-set:
* @widget: the object which received the signal.
* @palette_name: the name of the currently selected palette.
* @dialog_closing: whether the dialog was closed or not.
*
* The ::palette-set signal is emitted when the user selects a palette.
*
* Since: GIMP 2.4
*/
palette_button_signals[PALETTE_SET] =
g_signal_new ("palette-set",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpPaletteSelectButtonClass, palette_set),
NULL, NULL,
_gimpui_marshal_VOID__STRING_BOOLEAN,
G_TYPE_NONE, 2,
G_TYPE_STRING,
G_TYPE_BOOLEAN);
g_type_class_add_private (object_class,
sizeof (GimpPaletteSelectButtonPrivate));
}
static void
gimp_palette_select_button_init (GimpPaletteSelectButton *palette_button)
{
GimpPaletteSelectButtonPrivate *priv;
priv = GIMP_PALETTE_SELECT_BUTTON_GET_PRIVATE (palette_button);
priv->palette_name = NULL;
priv->inside = gimp_palette_select_button_create_inside (palette_button);
gtk_container_add (GTK_CONTAINER (palette_button), priv->inside);
}
/**
* gimp_palette_select_button_new:
* @title: Title of the dialog to use or %NULL to use the default title.
* @palette_name: Initial palette name.
*
* Creates a new #GtkWidget that completely controls the selection of
* a palette. This widget is suitable for placement in a table in a
* plug-in dialog.
*
* Returns: A #GtkWidget that you can use in your UI.
*
* Since: GIMP 2.4
*/
GtkWidget *
gimp_palette_select_button_new (const gchar *title,
const gchar *palette_name)
{
GtkWidget *palette_button;
if (title)
palette_button = g_object_new (GIMP_TYPE_PALETTE_SELECT_BUTTON,
"title", title,
"palette-name", palette_name,
NULL);
else
palette_button = g_object_new (GIMP_TYPE_PALETTE_SELECT_BUTTON,
"palette-name", palette_name,
NULL);
return palette_button;
}
/**
* gimp_palette_select_button_get_palette_name:
* @palette_button: A #GimpPaletteSelectButton
*
* Retrieves the name of currently selected palette.
*
* Returns: an internal copy of the palette name which must not be freed.
*
* Since: GIMP 2.4
*/
G_CONST_RETURN gchar *
gimp_palette_select_button_get_palette_name (GimpPaletteSelectButton *palette_button)
{
GimpPaletteSelectButtonPrivate *priv;
g_return_val_if_fail (GIMP_IS_PALETTE_SELECT_BUTTON (palette_button), NULL);
priv = GIMP_PALETTE_SELECT_BUTTON_GET_PRIVATE (palette_button);
return priv->palette_name;
}
/**
* gimp_palette_select_button_set_palette_name:
* @palette_button: A #GimpPaletteSelectButton
* @palette_name: Palette name to set; %NULL means no change.
*
* Sets the current palette for the palette select button.
*
* Since: GIMP 2.4
*/
void
gimp_palette_select_button_set_palette_name (GimpPaletteSelectButton *palette_button,
const gchar *palette_name)
{
GimpSelectButton *select_button;
g_return_if_fail (GIMP_IS_PALETTE_SELECT_BUTTON (palette_button));
select_button = GIMP_SELECT_BUTTON (palette_button);
if (select_button->temp_callback)
gimp_palettes_set_popup (select_button->temp_callback, palette_name);
else
gimp_palette_select_button_callback (palette_name, FALSE, palette_button);
}
/* private functions */
static void
gimp_palette_select_button_finalize (GObject *object)
{
GimpPaletteSelectButtonPrivate *priv;
priv = GIMP_PALETTE_SELECT_BUTTON_GET_PRIVATE (object);
g_free (priv->palette_name);
priv->palette_name = NULL;
g_free (priv->title);
priv->title = NULL;
G_OBJECT_CLASS (gimp_palette_select_button_parent_class)->finalize (object);
}
static void
gimp_palette_select_button_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpPaletteSelectButton *palette_button;
GimpPaletteSelectButtonPrivate *priv;
palette_button = GIMP_PALETTE_SELECT_BUTTON (object);
priv = GIMP_PALETTE_SELECT_BUTTON_GET_PRIVATE (palette_button);
switch (property_id)
{
case PROP_TITLE:
priv->title = g_value_dup_string (value);
break;
case PROP_PALETTE_NAME:
gimp_palette_select_button_set_palette_name (palette_button,
g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_palette_select_button_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpPaletteSelectButton *palette_button;
GimpPaletteSelectButtonPrivate *priv;
palette_button = GIMP_PALETTE_SELECT_BUTTON (object);
priv = GIMP_PALETTE_SELECT_BUTTON_GET_PRIVATE (palette_button);
switch (property_id)
{
case PROP_TITLE:
g_value_set_string (value, priv->title);
break;
case PROP_PALETTE_NAME:
g_value_set_string (value, priv->palette_name);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_palette_select_button_callback (const gchar *palette_name,
gboolean dialog_closing,
gpointer user_data)
{
GimpPaletteSelectButton *palette_button;
GimpPaletteSelectButtonPrivate *priv;
GimpSelectButton *select_button;
palette_button = GIMP_PALETTE_SELECT_BUTTON (user_data);
priv = GIMP_PALETTE_SELECT_BUTTON_GET_PRIVATE (palette_button);
select_button = GIMP_SELECT_BUTTON (palette_button);
g_free (priv->palette_name);
priv->palette_name = g_strdup (palette_name);
gtk_label_set_text (GTK_LABEL (priv->label), palette_name);
if (dialog_closing)
select_button->temp_callback = NULL;
g_signal_emit (palette_button, palette_button_signals[PALETTE_SET], 0,
palette_name, dialog_closing);
g_object_notify (G_OBJECT (palette_button), "palette-name");
}
static void
gimp_palette_select_button_clicked (GimpPaletteSelectButton *palette_button)
{
GimpPaletteSelectButtonPrivate *priv;
GimpSelectButton *select_button;
priv = GIMP_PALETTE_SELECT_BUTTON_GET_PRIVATE (palette_button);
select_button = GIMP_SELECT_BUTTON (palette_button);
if (select_button->temp_callback)
{
/* calling gimp_palettes_set_popup() raises the dialog */
gimp_palettes_set_popup (select_button->temp_callback,
priv->palette_name);
}
else
{
select_button->temp_callback =
gimp_palette_select_new (priv->title, priv->palette_name,
gimp_palette_select_button_callback,
palette_button);
}
}
static void
gimp_palette_select_drag_data_received (GimpPaletteSelectButton *palette_button,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time)
{
gchar *str;
if ((selection->format != 8) || (selection->length < 1))
{
g_warning ("Received invalid palette data!");
return;
}
str = g_strndup ((const gchar *) selection->data, selection->length);
if (g_utf8_validate (str, -1, NULL))
{
gint pid;
gpointer unused;
gint name_offset = 0;
if (sscanf (str, "%i:%p:%n", &pid, &unused, &name_offset) >= 2 &&
pid == gimp_getpid () && name_offset > 0)
{
gchar *name = str + name_offset;
gimp_palette_select_button_set_palette_name (palette_button, name);
}
}
g_free (str);
}
static GtkWidget *
gimp_palette_select_button_create_inside (GimpPaletteSelectButton *palette_button)
{
GtkWidget *button;
GtkWidget *hbox;
GtkWidget *image;
GimpPaletteSelectButtonPrivate *priv;
priv = GIMP_PALETTE_SELECT_BUTTON_GET_PRIVATE (palette_button);
gtk_widget_push_composite_child ();
button = gtk_button_new ();
hbox = gtk_hbox_new (FALSE, 4);
gtk_container_add (GTK_CONTAINER (button), hbox);
image = gtk_image_new_from_stock (GIMP_STOCK_PALETTE, GTK_ICON_SIZE_BUTTON);
gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
priv->label = gtk_label_new (priv->palette_name);
gtk_box_pack_start (GTK_BOX (hbox), priv->label, TRUE, TRUE, 4);
gtk_widget_show_all (button);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gimp_palette_select_button_clicked),
palette_button);
gtk_drag_dest_set (GTK_WIDGET (button),
GTK_DEST_DEFAULT_HIGHLIGHT |
GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_DROP,
&target, 1,
GDK_ACTION_COPY);
g_signal_connect_swapped (button, "drag-data-received",
G_CALLBACK (gimp_palette_select_drag_data_received),
palette_button);
gtk_widget_pop_composite_child ();
return button;
}

View File

@ -0,0 +1,76 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimppaletteselectbutton.h
*
* 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
* Lesser 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.
*/
#ifndef __GIMP_PALETTE_SELECT_BUTTON_H__
#define __GIMP_PALETTE_SELECT_BUTTON_H__
#include <libgimp/gimpselectbutton.h>
G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
#define GIMP_TYPE_PALETTE_SELECT_BUTTON (gimp_palette_select_button_get_type ())
#define GIMP_PALETTE_SELECT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PALETTE_SELECT_BUTTON, GimpPaletteSelectButton))
#define GIMP_PALETTE_SELECT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PALETTE_SELECT_BUTTON, GimpPaletteSelectButtonClass))
#define GIMP_IS_PALETTE_SELECT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_PALETTE_SELECT_BUTTON))
#define GIMP_IS_PALETTE_SELECT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PALETTE_SELECT_BUTTON))
#define GIMP_PALETTE_SELECT_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PALETTE_SELECT_BUTTON, GimpPaletteSelectButtonClass))
typedef struct _GimpPaletteSelectButtonClass GimpPaletteSelectButtonClass;
struct _GimpPaletteSelectButton
{
GimpSelectButton parent_instance;
};
struct _GimpPaletteSelectButtonClass
{
GimpSelectButtonClass parent_class;
/* palette_set signal is emitted when palette is chosen */
void (* palette_set) (GimpPaletteSelectButton *palette_button,
const gchar *palette_name,
gboolean dialog_closing);
/* Padding for future expansion */
void (*_gimp_reserved1) (void);
void (*_gimp_reserved2) (void);
void (*_gimp_reserved3) (void);
void (*_gimp_reserved4) (void);
};
GType gimp_palette_select_button_get_type (void) G_GNUC_CONST;
GtkWidget * gimp_palette_select_button_new (const gchar *title,
const gchar *palette_name);
G_CONST_RETURN gchar * gimp_palette_select_button_get_palette_name (GimpPaletteSelectButton *button);
void gimp_palette_select_button_set_palette_name (GimpPaletteSelectButton *button,
const gchar *palette_name);
G_END_DECLS
#endif /* __GIMP_PALETTE_SELECT_BUTTON_H__ */

View File

@ -22,77 +22,30 @@
#include "config.h"
#include <string.h>
#include "gimp.h"
#include "gimpui.h"
#include "libgimp-intl.h"
#include "gimpuitypes.h"
#include "gimppatternselectbutton.h"
#undef GIMP_DISABLE_DEPRECATED
#include "gimppatternmenu.h"
#define PATTERN_SELECT_DATA_KEY "gimp-pattern-select-data"
#define CELL_SIZE 20
typedef struct _CompatCallbackData CompatCallbackData;
typedef struct _PatternSelect PatternSelect;
struct _PatternSelect
struct _CompatCallbackData
{
gchar *title;
GimpRunPatternCallback callback;
gpointer data;
GtkWidget *preview;
GtkWidget *button;
GtkWidget *popup;
gchar *pattern_name; /* Local copy */
gint width;
gint height;
gint bytes;
guchar *mask_data; /* local copy */
const gchar *temp_pattern_callback;
GimpRunPatternCallback callback;
gpointer data;
};
static void gimp_pattern_select_widget_callback (const gchar *name,
gint width,
gint height,
gint bytes,
const guchar *mask_data,
gboolean closing,
gpointer data);
static void gimp_pattern_select_widget_clicked (GtkWidget *widget,
PatternSelect *pattern_sel);
static void gimp_pattern_select_widget_destroy (GtkWidget *widget,
PatternSelect *pattern_sel);
static gboolean gimp_pattern_select_preview_events (GtkWidget *widget,
GdkEvent *event,
PatternSelect *pattern_sel);
static void gimp_pattern_select_preview_update (GtkWidget *preview,
gint width,
gint height,
gint bytes,
const guchar *mask_data);
static void gimp_pattern_select_preview_resize (PatternSelect *pattern_sel);
static void gimp_pattern_select_popup_open (PatternSelect *pattern_sel,
gint x,
gint y);
static void gimp_pattern_select_popup_close (PatternSelect *pattern_sel);
static void gimp_pattern_select_drag_data_received (GtkWidget *preview,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time,
GtkWidget *widget);
static const GtkTargetEntry target = { "application/x-gimp-pattern-name", 0 };
static void compat_callback (GimpPatternSelectButton *pattern_button,
const gchar *pattern_name,
gint width,
gint height,
gint bytes,
const guchar *mask_data,
gboolean dialog_closing,
gpointer data);
/**
@ -114,81 +67,22 @@ gimp_pattern_select_widget_new (const gchar *title,
GimpRunPatternCallback callback,
gpointer data)
{
PatternSelect *pattern_sel;
GtkWidget *frame;
GtkWidget *hbox;
gint mask_data_size;
GtkWidget *pattern_button;
CompatCallbackData *compat_data;
g_return_val_if_fail (callback != NULL, NULL);
if (! title)
title = _("Pattern Selection");
pattern_button = gimp_pattern_select_button_new (title, pattern_name);
pattern_sel = g_new0 (PatternSelect, 1);
compat_data = g_new (CompatCallbackData, 1);
compat_data->callback = callback;
compat_data->data = data;
pattern_sel->title = g_strdup (title);
pattern_sel->callback = callback;
pattern_sel->data = data;
g_signal_connect_data (pattern_button, "pattern-set",
G_CALLBACK (compat_callback),
compat_data, (GClosureNotify) g_free, 0);
hbox = gtk_hbox_new (FALSE, 6);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
pattern_sel->preview = gimp_preview_area_new ();
gtk_widget_add_events (pattern_sel->preview,
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
gtk_widget_set_size_request (pattern_sel->preview, CELL_SIZE, CELL_SIZE);
gtk_container_add (GTK_CONTAINER (frame), pattern_sel->preview);
gtk_widget_show (pattern_sel->preview);
g_signal_connect_swapped (pattern_sel->preview, "size-allocate",
G_CALLBACK (gimp_pattern_select_preview_resize),
pattern_sel);
g_signal_connect (pattern_sel->preview, "event",
G_CALLBACK (gimp_pattern_select_preview_events),
pattern_sel);
gtk_drag_dest_set (GTK_WIDGET (pattern_sel->preview),
GTK_DEST_DEFAULT_HIGHLIGHT |
GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_DROP,
&target, 1,
GDK_ACTION_COPY);
g_signal_connect (pattern_sel->preview, "drag-data-received",
G_CALLBACK (gimp_pattern_select_drag_data_received),
hbox);
pattern_sel->button = gtk_button_new_with_mnemonic (_("_Browse..."));
gtk_box_pack_start (GTK_BOX (hbox), pattern_sel->button, TRUE, TRUE, 0);
gtk_widget_show (pattern_sel->button);
g_signal_connect (pattern_sel->button, "clicked",
G_CALLBACK (gimp_pattern_select_widget_clicked),
pattern_sel);
g_signal_connect (pattern_sel->button, "destroy",
G_CALLBACK (gimp_pattern_select_widget_destroy),
pattern_sel);
/* Do initial pattern setup */
if (! pattern_name || ! strlen (pattern_name))
pattern_sel->pattern_name = gimp_context_get_pattern ();
else
pattern_sel->pattern_name = g_strdup (pattern_name);
gimp_pattern_get_pixels (pattern_sel->pattern_name,
&pattern_sel->width,
&pattern_sel->height,
&pattern_sel->bytes,
&mask_data_size,
&pattern_sel->mask_data);
g_object_set_data (G_OBJECT (hbox), PATTERN_SELECT_DATA_KEY, pattern_sel);
return hbox;
return pattern_button;
}
/**
@ -200,19 +94,9 @@ gimp_pattern_select_widget_new (const gchar *title,
void
gimp_pattern_select_widget_close (GtkWidget *widget)
{
PatternSelect *pattern_sel;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_WIDGET (widget));
pattern_sel = g_object_get_data (G_OBJECT (widget), PATTERN_SELECT_DATA_KEY);
g_return_if_fail (pattern_sel != NULL);
if (pattern_sel->temp_pattern_callback)
{
gimp_pattern_select_destroy (pattern_sel->temp_pattern_callback);
pattern_sel->temp_pattern_callback = NULL;
}
gimp_select_button_close_popup (GIMP_SELECT_BUTTON (widget));
}
/**
@ -228,300 +112,24 @@ void
gimp_pattern_select_widget_set (GtkWidget *widget,
const gchar *pattern_name)
{
PatternSelect *pattern_sel;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_WIDGET (widget));
pattern_sel = g_object_get_data (G_OBJECT (widget), PATTERN_SELECT_DATA_KEY);
g_return_if_fail (pattern_sel != NULL);
if (pattern_sel->temp_pattern_callback)
{
gimp_patterns_set_popup (pattern_sel->temp_pattern_callback,
pattern_name);
}
else
{
gint width;
gint height;
gint bytes;
gint mask_data_size;
guint8 *mask_data;
gchar *name;
if (! pattern_name || ! strlen (pattern_name))
name = gimp_context_get_pattern ();
else
name = g_strdup (pattern_name);
if (gimp_pattern_get_pixels (name,
&width,
&height,
&bytes,
&mask_data_size,
&mask_data))
{
gimp_pattern_select_widget_callback (name, width, height, bytes,
mask_data, FALSE, pattern_sel);
g_free (mask_data);
}
g_free (name);
}
}
/* private functions */
static void
gimp_pattern_select_widget_callback (const gchar *name,
gint width,
gint height,
gint bytes,
const guchar *mask_data,
gboolean closing,
gpointer data)
{
PatternSelect *pattern_sel = (PatternSelect *) data;
g_free (pattern_sel->pattern_name);
g_free (pattern_sel->mask_data);
pattern_sel->pattern_name = g_strdup (name);
pattern_sel->width = width;
pattern_sel->height = height;
pattern_sel->bytes = bytes;
pattern_sel->mask_data = g_memdup (mask_data, width * height * bytes);
gimp_pattern_select_preview_update (pattern_sel->preview,
width, height, bytes, mask_data);
if (pattern_sel->callback)
pattern_sel->callback (name, width, height, bytes,
mask_data, closing, pattern_sel->data);
if (closing)
pattern_sel->temp_pattern_callback = NULL;
gimp_pattern_select_button_set_pattern_name
(GIMP_PATTERN_SELECT_BUTTON (widget), pattern_name);
}
static void
gimp_pattern_select_widget_clicked (GtkWidget *widget,
PatternSelect *pattern_sel)
compat_callback (GimpPatternSelectButton *pattern_button,
const gchar *pattern_name,
gint width,
gint height,
gint bpp,
const guchar *mask_data,
gboolean dialog_closing,
gpointer data)
{
if (pattern_sel->temp_pattern_callback)
{
/* calling gimp_patterns_set_popup() raises the dialog */
gimp_patterns_set_popup (pattern_sel->temp_pattern_callback,
pattern_sel->pattern_name);
}
else
{
pattern_sel->temp_pattern_callback =
gimp_pattern_select_new (pattern_sel->title,
pattern_sel->pattern_name,
gimp_pattern_select_widget_callback,
pattern_sel);
}
}
static void
gimp_pattern_select_widget_destroy (GtkWidget *widget,
PatternSelect *pattern_sel)
{
if (pattern_sel->temp_pattern_callback)
{
gimp_pattern_select_destroy (pattern_sel->temp_pattern_callback);
pattern_sel->temp_pattern_callback = NULL;
}
g_free (pattern_sel->title);
g_free (pattern_sel->pattern_name);
g_free (pattern_sel->mask_data);
g_free (pattern_sel);
}
static void
gimp_pattern_select_preview_resize (PatternSelect *pattern_sel)
{
if (pattern_sel->width > 0 && pattern_sel->height > 0)
gimp_pattern_select_preview_update (pattern_sel->preview,
pattern_sel->width,
pattern_sel->height,
pattern_sel->bytes,
pattern_sel->mask_data);
}
static gboolean
gimp_pattern_select_preview_events (GtkWidget *widget,
GdkEvent *event,
PatternSelect *pattern_sel)
{
GdkEventButton *bevent;
if (pattern_sel->mask_data)
{
switch (event->type)
{
case GDK_BUTTON_PRESS:
bevent = (GdkEventButton *) event;
if (bevent->button == 1)
{
gtk_grab_add (widget);
gimp_pattern_select_popup_open (pattern_sel,
bevent->x, bevent->y);
}
break;
case GDK_BUTTON_RELEASE:
bevent = (GdkEventButton *) event;
if (bevent->button == 1)
{
gtk_grab_remove (widget);
gimp_pattern_select_popup_close (pattern_sel);
}
break;
default:
break;
}
}
return FALSE;
}
static void
gimp_pattern_select_preview_update (GtkWidget *preview,
gint width,
gint height,
gint bytes,
const guchar *mask_data)
{
GimpImageType type;
switch (bytes)
{
case 1: type = GIMP_GRAY_IMAGE; break;
case 2: type = GIMP_GRAYA_IMAGE; break;
case 3: type = GIMP_RGB_IMAGE; break;
case 4: type = GIMP_RGBA_IMAGE; break;
default:
return;
}
gimp_preview_area_draw (GIMP_PREVIEW_AREA (preview),
0, 0, width, height,
type,
mask_data,
width * bytes);
}
static void
gimp_pattern_select_popup_open (PatternSelect *pattern_sel,
gint x,
gint y)
{
GtkWidget *frame;
GtkWidget *preview;
GdkScreen *screen;
gint x_org;
gint y_org;
gint scr_w;
gint scr_h;
if (pattern_sel->popup)
gimp_pattern_select_popup_close (pattern_sel);
if (pattern_sel->width <= CELL_SIZE && pattern_sel->height <= CELL_SIZE)
return;
pattern_sel->popup = gtk_window_new (GTK_WINDOW_POPUP);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (pattern_sel->popup), frame);
gtk_widget_show (frame);
preview = gimp_preview_area_new ();
gtk_widget_set_size_request (preview,
pattern_sel->width, pattern_sel->height);
gtk_container_add (GTK_CONTAINER (frame), preview);
gtk_widget_show (preview);
/* decide where to put the popup */
gdk_window_get_origin (pattern_sel->preview->window, &x_org, &y_org);
screen = gtk_widget_get_screen (pattern_sel->popup);
scr_w = gdk_screen_get_width (screen);
scr_h = gdk_screen_get_height (screen);
x = x_org + x - (pattern_sel->width / 2);
y = y_org + y - (pattern_sel->height / 2);
x = (x < 0) ? 0 : x;
y = (y < 0) ? 0 : y;
x = (x + pattern_sel->width > scr_w) ? scr_w - pattern_sel->width : x;
y = (y + pattern_sel->height > scr_h) ? scr_h - pattern_sel->height : y;
gtk_window_move (GTK_WINDOW (pattern_sel->popup), x, y);
gtk_widget_show (pattern_sel->popup);
/* Draw the pattern */
gimp_pattern_select_preview_update (preview,
pattern_sel->width, pattern_sel->height,
pattern_sel->bytes,
pattern_sel->mask_data);
}
static void
gimp_pattern_select_popup_close (PatternSelect *pattern_sel)
{
if (pattern_sel->popup)
{
gtk_widget_destroy (pattern_sel->popup);
pattern_sel->popup = NULL;
}
}
static void
gimp_pattern_select_drag_data_received (GtkWidget *preview,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time,
GtkWidget *widget)
{
gchar *str;
if ((selection->format != 8) || (selection->length < 1))
{
g_warning ("Received invalid pattern data!");
return;
}
str = g_strndup ((const gchar *) selection->data, selection->length);
if (g_utf8_validate (str, -1, NULL))
{
gint pid;
gpointer unused;
gint name_offset = 0;
if (sscanf (str, "%i:%p:%n", &pid, &unused, &name_offset) >= 2 &&
pid == gimp_getpid () && name_offset > 0)
{
gchar *name = str + name_offset;
gimp_pattern_select_widget_set (widget, name);
}
}
g_free (str);
CompatCallbackData *compat_data = data;
compat_data->callback (pattern_name, width, height, bpp, mask_data,
dialog_closing, compat_data->data);
}

View File

@ -22,6 +22,12 @@
#ifndef __GIMP_PATTERN_MENU_H__
#define __GIMP_PATTERN_MENU_H__
/* These functions are deprecated and should not be used in newly
* written code.
*/
#ifndef GIMP_DISABLE_DEPRECATED
G_BEGIN_DECLS
@ -37,4 +43,6 @@ void gimp_pattern_select_widget_set (GtkWidget *widget,
G_END_DECLS
#endif /* GIMP_DISABLE_DEPRECATED */
#endif /* __GIMP_PATTERN_MENU_H__ */

View File

@ -0,0 +1,724 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimppatternselectbutton.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 <gtk/gtk.h>
#include "libgimpwidgets/gimpwidgets.h"
#include "gimp.h"
#include "gimpuitypes.h"
#include "gimppatternselectbutton.h"
#include "gimpuimarshal.h"
#include "libgimp-intl.h"
#define CELL_SIZE 20
#define GIMP_PATTERN_SELECT_BUTTON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GIMP_TYPE_PATTERN_SELECT_BUTTON, GimpPatternSelectButtonPrivate))
typedef struct _GimpPatternSelectButtonPrivate GimpPatternSelectButtonPrivate;
struct _GimpPatternSelectButtonPrivate
{
gchar *title;
gchar *pattern_name; /* Local copy */
gint width;
gint height;
gint bytes;
guchar *mask_data; /* local copy */
GtkWidget *inside;
GtkWidget *preview;
GtkWidget *popup;
};
enum
{
PATTERN_SET,
LAST_SIGNAL
};
enum
{
PROP_0,
PROP_TITLE,
PROP_PATTERN_NAME
};
/* local function prototypes */
static void gimp_pattern_select_button_finalize (GObject *object);
static void gimp_pattern_select_button_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_pattern_select_button_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_pattern_select_button_clicked (GimpPatternSelectButton *pattern_button);
static void gimp_pattern_select_button_callback (const gchar *pattern_name,
gint width,
gint height,
gint bytes,
const guchar *mask_data,
gboolean dialog_closing,
gpointer user_data);
static void gimp_pattern_select_preview_resize (GimpPatternSelectButton *pattern_button);
static gboolean gimp_pattern_select_preview_events (GtkWidget *widget,
GdkEvent *event,
GimpPatternSelectButton *pattern_button);
static void gimp_pattern_select_preview_update (GtkWidget *preview,
gint width,
gint height,
gint bytes,
const guchar *mask_data);
static void gimp_pattern_select_button_open_popup (GimpPatternSelectButton *pattern_button,
gint x,
gint y);
static void gimp_pattern_select_button_close_popup (GimpPatternSelectButton *pattern_button);
static void gimp_pattern_select_drag_data_received (GimpPatternSelectButton *pattern_button,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time);
static GtkWidget * gimp_pattern_select_button_create_inside (GimpPatternSelectButton *pattern_button);
static const GtkTargetEntry target = { "application/x-gimp-pattern-name", 0 };
static guint pattern_button_signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (GimpPatternSelectButton, gimp_pattern_select_button,
GIMP_TYPE_SELECT_BUTTON)
static void
gimp_pattern_select_button_class_init (GimpPatternSelectButtonClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpSelectButtonClass *select_button_class = GIMP_SELECT_BUTTON_CLASS (klass);
object_class->finalize = gimp_pattern_select_button_finalize;
object_class->set_property = gimp_pattern_select_button_set_property;
object_class->get_property = gimp_pattern_select_button_get_property;
select_button_class->select_destroy = gimp_pattern_select_destroy;
klass->pattern_set = NULL;
/**
* GimpPatternSelectButton:title:
*
* The title to be used for the pattern selection popup dialog.
*
* Since: GIMP 2.4
*/
g_object_class_install_property (object_class, PROP_TITLE,
g_param_spec_string ("title",
"Title",
"The title to be used for the pattern selection popup dialog",
_("Pattern Selection"),
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
/**
* GimpPatternSelectButton:pattern-name:
*
* The name of the currently selected pattern.
*
* Since: GIMP 2.4
*/
g_object_class_install_property (object_class, PROP_PATTERN_NAME,
g_param_spec_string ("pattern-name",
"Pattern name",
"The name of the currently selected pattern",
NULL,
GIMP_PARAM_READWRITE));
/**
* GimpPatternSelectButton::pattern-set:
* @widget: the object which received the signal.
* @pattern_name: the name of the currently selected pattern.
* @width: width of the pattern
* @height: height of the pattern
* @bpp: bpp of the pattern
* @mask_data: pattern mask data
* @dialog_closing: whether the dialog was closed or not.
*
* The ::pattern-set signal is emitted when the user selects a pattern.
*
* Since: GIMP 2.4
*/
pattern_button_signals[PATTERN_SET] =
g_signal_new ("pattern-set",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpPatternSelectButtonClass, pattern_set),
NULL, NULL,
_gimpui_marshal_VOID__STRING_INT_INT_INT_POINTER_BOOLEAN,
G_TYPE_NONE, 6,
G_TYPE_STRING,
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_POINTER,
G_TYPE_BOOLEAN);
g_type_class_add_private (object_class,
sizeof (GimpPatternSelectButtonPrivate));
}
static void
gimp_pattern_select_button_init (GimpPatternSelectButton *pattern_button)
{
GimpPatternSelectButtonPrivate *priv;
gint mask_data_size;
priv = GIMP_PATTERN_SELECT_BUTTON_GET_PRIVATE (pattern_button);
priv->pattern_name = gimp_context_get_pattern ();
gimp_pattern_get_pixels (priv->pattern_name,
&priv->width,
&priv->height,
&priv->bytes,
&mask_data_size,
&priv->mask_data);
priv->inside = gimp_pattern_select_button_create_inside (pattern_button);
gtk_container_add (GTK_CONTAINER (pattern_button), priv->inside);
priv->popup = NULL;
}
/**
* gimp_pattern_select_button_new:
* @title: Title of the dialog to use or %NULL to use the default title.
* @pattern_name: Initial pattern name or %NULL to use current selection.
*
* Creates a new #GtkWidget that completely controls the selection of
* a pattern. This widget is suitable for placement in a table in a
* plug-in dialog.
*
* Returns: A #GtkWidget that you can use in your UI.
*
* Since: GIMP 2.4
*/
GtkWidget *
gimp_pattern_select_button_new (const gchar *title,
const gchar *pattern_name)
{
GtkWidget *pattern_button;
if (title)
pattern_button = g_object_new (GIMP_TYPE_PATTERN_SELECT_BUTTON,
"title", title,
"pattern-name", pattern_name,
NULL);
else
pattern_button = g_object_new (GIMP_TYPE_PATTERN_SELECT_BUTTON,
"pattern-name", pattern_name,
NULL);
return pattern_button;
}
/**
* gimp_pattern_select_button_get_pattern_name:
* @button: A #GimpPatternSelectButton
*
* Retrieves the name of currently selected pattern.
*
* Returns: an internal copy of the pattern name which must not be freed.
*
* Since: GIMP 2.4
*/
G_CONST_RETURN gchar *
gimp_pattern_select_button_get_pattern_name (GimpPatternSelectButton *pattern_button)
{
GimpPatternSelectButtonPrivate *priv;
g_return_val_if_fail (GIMP_IS_PATTERN_SELECT_BUTTON (pattern_button), NULL);
priv = GIMP_PATTERN_SELECT_BUTTON_GET_PRIVATE (pattern_button);
return priv->pattern_name;
}
/**
* gimp_pattern_select_button_set_pattern_name:
* @pattern_button: A #GimpPatternSelectButton
* @pattern_name: Pattern name to set; %NULL means no change.
*
* Sets the current pattern for the pattern select button.
*
* Since: GIMP 2.4
*/
void
gimp_pattern_select_button_set_pattern_name (GimpPatternSelectButton *pattern_button,
const gchar *pattern_name)
{
GimpSelectButton *select_button;
g_return_if_fail (GIMP_IS_PATTERN_SELECT_BUTTON (pattern_button));
select_button = GIMP_SELECT_BUTTON (pattern_button);
if (select_button->temp_callback)
{
gimp_patterns_set_popup (select_button->temp_callback, pattern_name);
}
else
{
gchar *name;
gint width;
gint height;
gint bytes;
gint mask_data_size;
guint8 *mask_data;
if (pattern_name && *pattern_name)
name = g_strdup (pattern_name);
else
name = gimp_context_get_pattern ();
if (gimp_pattern_get_pixels (name,
&width,
&height,
&bytes,
&mask_data_size,
&mask_data))
{
gimp_pattern_select_button_callback (name,
width, height, bytes, mask_data,
FALSE, pattern_button);
g_free (mask_data);
}
g_free (name);
}
}
/* private functions */
static void
gimp_pattern_select_button_finalize (GObject *object)
{
GimpPatternSelectButtonPrivate *priv;
priv = GIMP_PATTERN_SELECT_BUTTON_GET_PRIVATE (object);
g_free (priv->pattern_name);
priv->pattern_name = NULL;
g_free (priv->mask_data);
priv->mask_data = NULL;
g_free (priv->title);
priv->title = NULL;
G_OBJECT_CLASS (gimp_pattern_select_button_parent_class)->finalize (object);
}
static void
gimp_pattern_select_button_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpPatternSelectButton *pattern_button;
GimpPatternSelectButtonPrivate *priv;
pattern_button = GIMP_PATTERN_SELECT_BUTTON (object);
priv = GIMP_PATTERN_SELECT_BUTTON_GET_PRIVATE (pattern_button);
switch (property_id)
{
case PROP_TITLE:
priv->title = g_value_dup_string (value);
break;
case PROP_PATTERN_NAME:
gimp_pattern_select_button_set_pattern_name (pattern_button,
g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_pattern_select_button_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpPatternSelectButton *pattern_button;
GimpPatternSelectButtonPrivate *priv;
pattern_button = GIMP_PATTERN_SELECT_BUTTON (object);
priv = GIMP_PATTERN_SELECT_BUTTON_GET_PRIVATE (pattern_button);
switch (property_id)
{
case PROP_TITLE:
g_value_set_string (value, priv->title);
break;
case PROP_PATTERN_NAME:
g_value_set_string (value, priv->pattern_name);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_pattern_select_button_callback (const gchar *pattern_name,
gint width,
gint height,
gint bytes,
const guchar *mask_data,
gboolean dialog_closing,
gpointer user_data)
{
GimpPatternSelectButton *pattern_button;
GimpPatternSelectButtonPrivate *priv;
GimpSelectButton *select_button;
pattern_button = GIMP_PATTERN_SELECT_BUTTON (user_data);
priv = GIMP_PATTERN_SELECT_BUTTON_GET_PRIVATE (pattern_button);
select_button = GIMP_SELECT_BUTTON (pattern_button);
g_free (priv->pattern_name);
g_free (priv->mask_data);
priv->pattern_name = g_strdup (pattern_name);
priv->width = width;
priv->height = height;
priv->bytes = bytes;
priv->mask_data = g_memdup (mask_data, width * height * bytes);
gimp_pattern_select_preview_update (priv->preview,
width, height, bytes, mask_data);
if (dialog_closing)
select_button->temp_callback = NULL;
g_signal_emit (pattern_button, pattern_button_signals[PATTERN_SET], 0,
pattern_name, width, height, bytes, dialog_closing);
g_object_notify (G_OBJECT (pattern_button), "pattern-name");
}
static void
gimp_pattern_select_button_clicked (GimpPatternSelectButton *pattern_button)
{
GimpPatternSelectButtonPrivate *priv;
GimpSelectButton *select_button;
priv = GIMP_PATTERN_SELECT_BUTTON_GET_PRIVATE (pattern_button);
select_button = GIMP_SELECT_BUTTON (pattern_button);
if (select_button->temp_callback)
{
/* calling gimp_patterns_set_popup() raises the dialog */
gimp_patterns_set_popup (select_button->temp_callback,
priv->pattern_name);
}
else
{
select_button->temp_callback =
gimp_pattern_select_new (priv->title, priv->pattern_name,
gimp_pattern_select_button_callback,
pattern_button);
}
}
static void
gimp_pattern_select_preview_resize (GimpPatternSelectButton *pattern_button)
{
GimpPatternSelectButtonPrivate *priv;
priv = GIMP_PATTERN_SELECT_BUTTON_GET_PRIVATE (pattern_button);
if (priv->width > 0 && priv->height > 0)
gimp_pattern_select_preview_update (priv->preview,
priv->width,
priv->height,
priv->bytes,
priv->mask_data);
}
static gboolean
gimp_pattern_select_preview_events (GtkWidget *widget,
GdkEvent *event,
GimpPatternSelectButton *pattern_button)
{
GimpPatternSelectButtonPrivate *priv;
GdkEventButton *bevent;
priv = GIMP_PATTERN_SELECT_BUTTON_GET_PRIVATE (pattern_button);
if (priv->mask_data)
{
switch (event->type)
{
case GDK_BUTTON_PRESS:
bevent = (GdkEventButton *) event;
if (bevent->button == 1)
{
gtk_grab_add (widget);
gimp_pattern_select_button_open_popup (pattern_button,
bevent->x, bevent->y);
}
break;
case GDK_BUTTON_RELEASE:
bevent = (GdkEventButton *) event;
if (bevent->button == 1)
{
gtk_grab_remove (widget);
gimp_pattern_select_button_close_popup (pattern_button);
}
break;
default:
break;
}
}
return FALSE;
}
static void
gimp_pattern_select_preview_update (GtkWidget *preview,
gint width,
gint height,
gint bytes,
const guchar *mask_data)
{
GimpImageType type;
switch (bytes)
{
case 1: type = GIMP_GRAY_IMAGE; break;
case 2: type = GIMP_GRAYA_IMAGE; break;
case 3: type = GIMP_RGB_IMAGE; break;
case 4: type = GIMP_RGBA_IMAGE; break;
default:
return;
}
gimp_preview_area_draw (GIMP_PREVIEW_AREA (preview),
0, 0, width, height,
type,
mask_data,
width * bytes);
}
static void
gimp_pattern_select_button_open_popup (GimpPatternSelectButton *pattern_button,
gint x,
gint y)
{
GimpPatternSelectButtonPrivate *priv;
GtkWidget *frame;
GtkWidget *preview;
GdkScreen *screen;
gint x_org;
gint y_org;
gint scr_w;
gint scr_h;
priv = GIMP_PATTERN_SELECT_BUTTON_GET_PRIVATE (pattern_button);
if (priv->popup)
gimp_pattern_select_button_close_popup (pattern_button);
if (priv->width <= CELL_SIZE && priv->height <= CELL_SIZE)
return;
priv->popup = gtk_window_new (GTK_WINDOW_POPUP);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (priv->popup), frame);
gtk_widget_show (frame);
preview = gimp_preview_area_new ();
gtk_widget_set_size_request (preview, priv->width, priv->height);
gtk_container_add (GTK_CONTAINER (frame), preview);
gtk_widget_show (preview);
/* decide where to put the popup */
gdk_window_get_origin (priv->preview->window, &x_org, &y_org);
screen = gtk_widget_get_screen (priv->popup);
scr_w = gdk_screen_get_width (screen);
scr_h = gdk_screen_get_height (screen);
x = x_org + x - (priv->width / 2);
y = y_org + y - (priv->height / 2);
x = (x < 0) ? 0 : x;
y = (y < 0) ? 0 : y;
x = (x + priv->width > scr_w) ? scr_w - priv->width : x;
y = (y + priv->height > scr_h) ? scr_h - priv->height : y;
gtk_window_move (GTK_WINDOW (priv->popup), x, y);
gtk_widget_show (priv->popup);
/* Draw the pattern */
gimp_pattern_select_preview_update (preview,
priv->width,
priv->height,
priv->bytes,
priv->mask_data);
}
static void
gimp_pattern_select_button_close_popup (GimpPatternSelectButton *pattern_button)
{
GimpPatternSelectButtonPrivate *priv;
priv = GIMP_PATTERN_SELECT_BUTTON_GET_PRIVATE (pattern_button);
if (priv->popup)
{
gtk_widget_destroy (priv->popup);
priv->popup = NULL;
}
}
static void
gimp_pattern_select_drag_data_received (GimpPatternSelectButton *pattern_button,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection,
guint info,
guint time)
{
gchar *str;
if ((selection->format != 8) || (selection->length < 1))
{
g_warning ("Received invalid pattern data!");
return;
}
str = g_strndup ((const gchar *) selection->data, selection->length);
if (g_utf8_validate (str, -1, NULL))
{
gint pid;
gpointer unused;
gint name_offset = 0;
if (sscanf (str, "%i:%p:%n", &pid, &unused, &name_offset) >= 2 &&
pid == gimp_getpid () && name_offset > 0)
{
gchar *name = str + name_offset;
gimp_pattern_select_button_set_pattern_name (pattern_button, name);
}
}
g_free (str);
}
static GtkWidget *
gimp_pattern_select_button_create_inside (GimpPatternSelectButton *pattern_button)
{
GtkWidget *hbox;
GtkWidget *frame;
GtkWidget *button;
GimpPatternSelectButtonPrivate *priv;
priv = GIMP_PATTERN_SELECT_BUTTON_GET_PRIVATE (pattern_button);
gtk_widget_push_composite_child ();
hbox = gtk_hbox_new (FALSE, 6);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0);
priv->preview = gimp_preview_area_new ();
gtk_widget_add_events (priv->preview,
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
gtk_widget_set_size_request (priv->preview, CELL_SIZE, CELL_SIZE);
gtk_container_add (GTK_CONTAINER (frame), priv->preview);
g_signal_connect_swapped (priv->preview, "size-allocate",
G_CALLBACK (gimp_pattern_select_preview_resize),
pattern_button);
g_signal_connect (priv->preview, "event",
G_CALLBACK (gimp_pattern_select_preview_events),
pattern_button);
gtk_drag_dest_set (GTK_WIDGET (priv->preview),
GTK_DEST_DEFAULT_HIGHLIGHT |
GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_DROP,
&target, 1,
GDK_ACTION_COPY);
g_signal_connect (priv->preview, "drag-data-received",
G_CALLBACK (gimp_pattern_select_drag_data_received),
hbox);
button = gtk_button_new_with_mnemonic (_("_Browse..."));
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gimp_pattern_select_button_clicked),
pattern_button);
gtk_widget_show_all (hbox);
gtk_widget_pop_composite_child ();
return hbox;
}

View File

@ -0,0 +1,80 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimppatternselectbutton.h
*
* 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
* Lesser 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.
*/
#ifndef __GIMP_PATTERN_SELECT_BUTTON_H__
#define __GIMP_PATTERN_SELECT_BUTTON_H__
#include <libgimp/gimpselectbutton.h>
G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
#define GIMP_TYPE_PATTERN_SELECT_BUTTON (gimp_pattern_select_button_get_type ())
#define GIMP_PATTERN_SELECT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PATTERN_SELECT_BUTTON, GimpPatternSelectButton))
#define GIMP_PATTERN_SELECT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PATTERN_SELECT_BUTTON, GimpPatternSelectButtonClass))
#define GIMP_IS_PATTERN_SELECT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_PATTERN_SELECT_BUTTON))
#define GIMP_IS_PATTERN_SELECT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PATTERN_SELECT_BUTTON))
#define GIMP_PATTERN_SELECT_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PATTERN_SELECT_BUTTON, GimpPatternSelectButtonClass))
typedef struct _GimpPatternSelectButtonClass GimpPatternSelectButtonClass;
struct _GimpPatternSelectButton
{
GimpSelectButton parent_instance;
};
struct _GimpPatternSelectButtonClass
{
GimpSelectButtonClass parent_class;
/* pattern_set signal is emitted when pattern is chosen */
void (* pattern_set) (GimpPatternSelectButton *pattern_button,
const gchar *pattern_name,
gint width,
gint height,
gint bpp,
const guchar *mask_data,
gboolean dialog_closing);
/* Padding for future expansion */
void (*_gimp_reserved1) (void);
void (*_gimp_reserved2) (void);
void (*_gimp_reserved3) (void);
void (*_gimp_reserved4) (void);
};
GType gimp_pattern_select_button_get_type (void) G_GNUC_CONST;
GtkWidget * gimp_pattern_select_button_new (const gchar *title,
const gchar *pattern_name);
G_CONST_RETURN gchar * gimp_pattern_select_button_get_pattern_name (GimpPatternSelectButton *button);
void gimp_pattern_select_button_set_pattern_name (GimpPatternSelectButton *button,
const gchar *pattern_name);
G_END_DECLS
#endif /* __GIMP_PATTERN_SELECT_BUTTON_H__ */

View File

@ -0,0 +1,83 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimpselectbutton.c
* Copyright (C) 2003 Sven Neumann <sven@gimp.org>
*
* 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 "gimp.h"
#include "gimpuitypes.h"
#include "gimpselectbutton.h"
/* local function prototypes */
static void gimp_select_button_destroy (GtkObject *object);
G_DEFINE_TYPE (GimpSelectButton, gimp_select_button, GTK_TYPE_HBOX)
static void
gimp_select_button_class_init (GimpSelectButtonClass *klass)
{
GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
object_class->destroy = gimp_select_button_destroy;
}
static void
gimp_select_button_init (GimpSelectButton *select_button)
{
select_button->temp_callback = NULL;
}
/**
* gimp_select_button_close_popup:
* @select_button: A #GimpSelectButton
*
* Closes the popup window associated with @select_button.
*
* Since: GIMP 2.4
*/
void
gimp_select_button_close_popup (GimpSelectButton *select_button)
{
g_return_if_fail (GIMP_IS_SELECT_BUTTON (select_button));
if (select_button->temp_callback)
{
GIMP_SELECT_BUTTON_GET_CLASS (select_button)->select_destroy
(select_button->temp_callback);
select_button->temp_callback = NULL;
}
}
/* private functions */
static void
gimp_select_button_destroy (GtkObject *object)
{
GimpSelectButton *select_button = GIMP_SELECT_BUTTON (object);
gimp_select_button_close_popup (select_button);
GTK_OBJECT_CLASS (gimp_select_button_parent_class)->destroy (object);
}

View File

@ -0,0 +1,75 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimpselectbutton.h
*
* 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
* Lesser 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.
*/
#ifndef __GIMP_SELECT_BUTTON_H__
#define __GIMP_SELECT_BUTTON_H__
#include <gtk/gtkhbox.h>
G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
#define GIMP_TYPE_SELECT_BUTTON (gimp_select_button_get_type ())
#define GIMP_SELECT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_SELECT_BUTTON, GimpSelectButton))
#define GIMP_SELECT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_SELECT_BUTTON, GimpSelectButtonClass))
#define GIMP_IS_SELECT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_SELECT_BUTTON))
#define GIMP_IS_SELECT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_SELECT_BUTTON))
#define GIMP_SELECT_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_SELECT_BUTTON, GimpSelectButtonClass))
typedef struct _GimpSelectButtonClass GimpSelectButtonClass;
struct _GimpSelectButton
{
GtkHBox parent_instance;
const gchar *temp_callback;
};
struct _GimpSelectButtonClass
{
GtkHBoxClass parent_class;
gchar *default_title;
void (*select_destroy) (const gchar *callback);
/* Padding for future expansion */
void (*_gimp_reserved1) (void);
void (*_gimp_reserved2) (void);
void (*_gimp_reserved3) (void);
void (*_gimp_reserved4) (void);
void (*_gimp_reserved5) (void);
void (*_gimp_reserved6) (void);
void (*_gimp_reserved7) (void);
};
GType gimp_select_button_get_type (void) G_GNUC_CONST;
void gimp_select_button_close_popup (GimpSelectButton *button);
G_END_DECLS
#endif /* __GIMP_SELECT_BUTTON_H__ */

View File

@ -29,8 +29,8 @@
#include <libgimp/gimpexport.h>
#include <libgimp/gimpmenu.h>
#include <libgimp/gimpaspectpreview.h>
#include <libgimp/gimpbrushmenu.h>
#include <libgimp/gimpdrawablepreview.h>
#include <libgimp/gimpbrushmenu.h>
#include <libgimp/gimpfontmenu.h>
#include <libgimp/gimpgradientmenu.h>
#include <libgimp/gimppalettemenu.h>
@ -41,7 +41,12 @@
#include <libgimp/gimpprogressbar.h>
#include <libgimp/gimpdrawablecombobox.h>
#include <libgimp/gimpimagecombobox.h>
#include <libgimp/gimpselectbutton.h>
#include <libgimp/gimpbrushselectbutton.h>
#include <libgimp/gimpfontselectbutton.h>
#include <libgimp/gimpgradientselectbutton.h>
#include <libgimp/gimppaletteselectbutton.h>
#include <libgimp/gimppatternselectbutton.h>
#include <libgimp/gimpzoompreview.h>
G_BEGIN_DECLS

View File

@ -23,3 +23,6 @@
# BOOL deprecated alias for BOOLEAN
VOID: STRING, BOOLEAN
VOID: STRING, INT, POINTER, BOOLEAN
VOID: STRING, INT, INT, INT, POINTER, BOOLEAN
VOID: STRING, DOUBLE, INT, INT, INT, INT, POINTER, BOOLEAN

View File

@ -40,6 +40,7 @@ typedef struct _GimpChannelComboBox GimpChannelComboBox;
typedef struct _GimpLayerComboBox GimpLayerComboBox;
typedef struct _GimpImageComboBox GimpImageComboBox;
typedef struct _GimpSelectButton GimpSelectButton;
typedef struct _GimpBrushSelectButton GimpBrushSelectButton;
typedef struct _GimpFontSelectButton GimpFontSelectButton;
typedef struct _GimpGradientSelectButton GimpGradientSelectButton;

View File

@ -284,11 +284,12 @@ explorer_number_of_colors_callback (GtkAdjustment *adjustment,
}
static void
explorer_gradient_select_callback (const gchar *name,
gint width,
const gdouble *gradient_data,
gboolean dialog_closing,
gpointer data)
explorer_gradient_select_callback (GimpGradientSelectButton *gradient_button,
const gchar *name,
gint width,
const gdouble *gradient_data,
gboolean dialog_closing,
gpointer data)
{
g_free (gradient_name);
g_free (gradient_samples);
@ -1160,10 +1161,10 @@ explorer_dialog (void)
&n_gradient_samples,
&gradient_samples);
gradient = gimp_gradient_select_widget_new (_("FractalExplorer Gradient"),
gradient_name,
explorer_gradient_select_callback,
NULL);
gradient = gimp_gradient_select_button_new (_("FractalExplorer Gradient"),
gradient_name);
g_signal_connect (gradient, "gradient-set",
G_CALLBACK (explorer_gradient_select_callback), NULL);
g_free (gradient_name);
gtk_box_pack_start (GTK_BOX (hbox), gradient, FALSE, FALSE, 0);
gtk_widget_show (gradient);

View File

@ -396,11 +396,11 @@ gfig_dialog (void)
/* brush selector in Stroke frame */
gfig_context->brush_select
= gimp_brush_select_widget_new ("Brush",
= gimp_brush_select_button_new ("Brush",
gfig_context->default_style.brush_name,
-1, -1, -1,
gfig_brush_changed_callback,
NULL);
-1.0, -1, -1);
g_signal_connect (gfig_context->brush_select, "brush-set",
G_CALLBACK (gfig_brush_changed_callback), NULL);
gtk_box_pack_start (GTK_BOX (vbox), gfig_context->brush_select,
FALSE, FALSE, 0);
gtk_widget_show (gfig_context->brush_select);
@ -463,18 +463,18 @@ gfig_dialog (void)
/* A page for the pattern selector */
gfig_context->pattern_select
= gimp_pattern_select_widget_new ("Pattern", gfig_context->default_style.pattern,
gfig_pattern_changed_callback,
NULL);
= gimp_pattern_select_button_new ("Pattern", gfig_context->default_style.pattern);
g_signal_connect (gfig_context->pattern_select, "pattern-set",
G_CALLBACK (gfig_pattern_changed_callback), NULL);
gtk_widget_show (gfig_context->pattern_select);
gtk_notebook_append_page (GTK_NOTEBOOK (fill_type_notebook),
gfig_context->pattern_select, NULL);
/* A page for the gradient selector */
gfig_context->gradient_select
= gimp_gradient_select_widget_new ("Gradient", gfig_context->default_style.gradient,
gfig_gradient_changed_callback,
NULL);
= gimp_gradient_select_button_new ("Gradient", gfig_context->default_style.gradient);
g_signal_connect (gfig_context->gradient_select, "gradient-set",
G_CALLBACK (gfig_gradient_changed_callback), NULL);
gtk_widget_show (gfig_context->gradient_select);
gtk_notebook_append_page (GTK_NOTEBOOK (fill_type_notebook),
gfig_context->gradient_select, NULL);

View File

@ -479,15 +479,16 @@ set_paint_type_callback (GtkToggleButton *toggle,
* gfig_context->enable_repaint is FALSE).
*/
void
gfig_brush_changed_callback (const gchar *brush_name,
gdouble opacity,
gint spacing,
GimpLayerModeEffects paint_mode,
gint width,
gint height,
const guchar *mask_data,
gboolean dialog_closing,
gpointer user_data)
gfig_brush_changed_callback (GimpBrushSelectButton *button,
const gchar *brush_name,
gdouble opacity,
gint spacing,
GimpLayerModeEffects paint_mode,
gint width,
gint height,
const guchar *mask_data,
gboolean dialog_closing,
gpointer user_data)
{
Style *current_style;
@ -504,13 +505,14 @@ gfig_brush_changed_callback (const gchar *brush_name,
}
void
gfig_pattern_changed_callback (const gchar *pattern_name,
gint width,
gint height,
gint bpp,
const guchar *mask_data,
gboolean dialog_closing,
gpointer user_data)
gfig_pattern_changed_callback (GimpPatternSelectButton *button,
const gchar *pattern_name,
gint width,
gint height,
gint bpp,
const guchar *mask_data,
gboolean dialog_closing,
gpointer user_data)
{
Style *current_style;
@ -521,11 +523,12 @@ gfig_pattern_changed_callback (const gchar *pattern_name,
}
void
gfig_gradient_changed_callback (const gchar *gradient_name,
gint width,
const gdouble *grad_data,
gboolean dialog_closing,
gpointer user_data)
gfig_gradient_changed_callback (GimpGradientSelectButton *button,
const gchar *gradient_name,
gint width,
const gdouble *grad_data,
gboolean dialog_closing,
gpointer user_data)
{
Style *current_style;
@ -663,15 +666,17 @@ gfig_style_set_context_from_style (Style *style)
g_message ("Style from context: Failed to set brush to '%s'",
style->brush_name);
gimp_brush_select_widget_set (gfig_context->brush_select,
style->brush_name,
-1., -1, -1); /* FIXME */
gimp_brush_select_button_set_brush
(GIMP_BRUSH_SELECT_BUTTON (gfig_context->brush_select),
style->brush_name, -1.0, -1, -1); /* FIXME */
gimp_pattern_select_widget_set (gfig_context->pattern_select,
style->pattern);
gimp_pattern_select_button_set_pattern_name
(GIMP_PATTERN_SELECT_BUTTON (gfig_context->pattern_select),
style->pattern);
gimp_gradient_select_widget_set (gfig_context->gradient_select,
style->gradient);
gimp_gradient_select_button_set_gradient_name
(GIMP_GRADIENT_SELECT_BUTTON (gfig_context->gradient_select),
style->gradient);
gfig_context->bdesc.name = style->brush_name;
if (gfig_context->debug_styles)

View File

@ -76,7 +76,8 @@ void set_background_callback (GimpColorButton *button,
void set_paint_type_callback (GtkToggleButton *toggle,
gpointer data);
void gfig_brush_changed_callback (const gchar *brush_name,
void gfig_brush_changed_callback (GimpBrushSelectButton *button,
const gchar *brush_name,
gdouble opacity,
gint spacing,
GimpLayerModeEffects paint_mode,
@ -86,7 +87,8 @@ void gfig_brush_changed_callback (const gchar *brush_name,
gboolean dialog_closing,
gpointer user_data);
void gfig_pattern_changed_callback (const gchar *pattern_name,
void gfig_pattern_changed_callback (GimpPatternSelectButton *button,
const gchar *pattern_name,
gint width,
gint height,
gint bpp,
@ -94,7 +96,8 @@ void gfig_pattern_changed_callback (const gchar *pattern_name,
gboolean dialog_closing,
gpointer user_data);
void gfig_gradient_changed_callback (const gchar *gradient_name,
void gfig_gradient_changed_callback (GimpGradientSelectButton *button,
const gchar *gradient_name,
gint width,
const gdouble *grad_data,
gboolean dialog_closing,

View File

@ -75,33 +75,33 @@ static void script_fu_file_callback (GtkWidget *widget,
SFFilename *file);
static void script_fu_combo_callback (GtkWidget *widget,
SFOption *option);
static void script_fu_pattern_callback (const gchar *name,
static void script_fu_pattern_callback (gpointer data,
const gchar *name,
gint width,
gint height,
gint bytes,
const guchar *mask_data,
gboolean closing,
gpointer data);
static void script_fu_gradient_callback (const gchar *name,
gboolean closing);
static void script_fu_gradient_callback (gpointer data,
const gchar *name,
gint width,
const gdouble *mask_data,
gboolean closing,
gpointer data);
gboolean closing);
static void script_fu_font_callback (gpointer data,
const gchar *name,
gboolean closing);
static void script_fu_palette_callback (const gchar *name,
gboolean closing,
gpointer data);
static void script_fu_brush_callback (const gchar *name,
static void script_fu_palette_callback (gpointer data,
const gchar *name,
gboolean closing);
static void script_fu_brush_callback (gpointer data,
const gchar *name,
gdouble opacity,
gint spacing,
GimpLayerModeEffects paint_mode,
gint width,
gint height,
const guchar *mask_data,
gboolean closing,
gpointer data);
gboolean closing);
/*
@ -449,44 +449,49 @@ script_fu_interface (SFScript *script)
break;
case SF_FONT:
widget = gimp_font_select_button_new (_("Script-Fu Font Selection"),
widget = gimp_font_select_button_new (_("Script-Fu Font Selection"),
script->arg_values[i].sfa_font);
g_signal_connect_swapped (widget, "font-set",
G_CALLBACK (script_fu_font_callback),
&script->arg_values[i].sfa_font);
break;
break;
case SF_PALETTE:
widget = gimp_palette_select_widget_new (_("Script-Fu Palette Selection"),
script->arg_values[i].sfa_palette,
script_fu_palette_callback,
&script->arg_values[i].sfa_palette);
break;
widget = gimp_palette_select_button_new (_("Script-Fu Palette Selection"),
script->arg_values[i].sfa_palette);
g_signal_connect_swapped (widget, "palette-set",
G_CALLBACK (script_fu_palette_callback),
&script->arg_values[i].sfa_palette);
break;
case SF_PATTERN:
left_align = TRUE;
widget = gimp_pattern_select_widget_new (_("Script-fu Pattern Selection"),
script->arg_values[i].sfa_pattern,
script_fu_pattern_callback,
&script->arg_values[i].sfa_pattern);
break;
widget = gimp_pattern_select_button_new (_("Script-fu Pattern Selection"),
script->arg_values[i].sfa_pattern);
g_signal_connect_swapped (widget, "pattern-set",
G_CALLBACK (script_fu_pattern_callback),
&script->arg_values[i].sfa_pattern);
break;
case SF_GRADIENT:
left_align = TRUE;
widget = gimp_gradient_select_widget_new (_("Script-Fu Gradient Selection"),
script->arg_values[i].sfa_gradient,
script_fu_gradient_callback,
&script->arg_values[i].sfa_gradient);
break;
widget = gimp_gradient_select_button_new (_("Script-Fu Gradient Selection"),
script->arg_values[i].sfa_gradient);
g_signal_connect_swapped (widget, "gradient-set",
G_CALLBACK (script_fu_gradient_callback),
&script->arg_values[i].sfa_gradient);
break;
case SF_BRUSH:
left_align = TRUE;
widget = gimp_brush_select_widget_new (_("Script-Fu Brush Selection"),
widget = gimp_brush_select_button_new (_("Script-Fu Brush Selection"),
script->arg_values[i].sfa_brush.name,
script->arg_values[i].sfa_brush.opacity,
script->arg_values[i].sfa_brush.spacing,
script->arg_values[i].sfa_brush.paint_mode,
script_fu_brush_callback,
&script->arg_values[i].sfa_brush);
script->arg_values[i].sfa_brush.paint_mode);
g_signal_connect_swapped (widget, "brush-set",
G_CALLBACK (script_fu_brush_callback),
&script->arg_values[i].sfa_brush);
break;
case SF_OPTION:
@ -586,24 +591,12 @@ script_fu_interface_quit (SFScript *script)
switch (script->arg_types[i])
{
case SF_FONT:
gimp_font_select_button_close_popup
(GIMP_FONT_SELECT_BUTTON (sf_interface->widgets[i]));
break;
case SF_PALETTE:
gimp_palette_select_widget_close (sf_interface->widgets[i]);
break;
case SF_PATTERN:
gimp_pattern_select_widget_close (sf_interface->widgets[i]);
break;
case SF_GRADIENT:
gimp_gradient_select_widget_close (sf_interface->widgets[i]);
break;
case SF_BRUSH:
gimp_brush_select_widget_close (sf_interface->widgets[i]);
gimp_select_button_close_popup
(GIMP_SELECT_BUTTON (sf_interface->widgets[i]));
break;
default:
@ -653,23 +646,23 @@ script_fu_string_update (gchar **dest,
}
static void
script_fu_pattern_callback (const gchar *name,
script_fu_pattern_callback (gpointer data,
const gchar *name,
gint width,
gint height,
gint bytes,
const guchar *mask_data,
gboolean closing,
gpointer data)
gboolean closing)
{
script_fu_string_update (data, name);
}
static void
script_fu_gradient_callback (const gchar *name,
script_fu_gradient_callback (gpointer data,
const gchar *name,
gint width,
const gdouble *mask_data,
gboolean closing,
gpointer data)
gboolean closing)
{
script_fu_string_update (data, name);
}
@ -683,23 +676,23 @@ script_fu_font_callback (gpointer data,
}
static void
script_fu_palette_callback (const gchar *name,
gboolean closing,
gpointer data)
script_fu_palette_callback (gpointer data,
const gchar *name,
gboolean closing)
{
script_fu_string_update (data, name);
}
static void
script_fu_brush_callback (const gchar *name,
script_fu_brush_callback (gpointer data,
const gchar *name,
gdouble opacity,
gint spacing,
GimpLayerModeEffects paint_mode,
gint width,
gint height,
const guchar *mask_data,
gboolean closing,
gpointer data)
gboolean closing)
{
SFBrush *brush = data;
@ -951,26 +944,30 @@ script_fu_reset (SFScript *script)
break;
case SF_PALETTE:
gimp_palette_select_widget_set (widget,
script->arg_defaults[i].sfa_palette);
gimp_palette_select_button_set_palette_name
(GIMP_PALETTE_SELECT_BUTTON (widget),
script->arg_defaults[i].sfa_palette);
break;
case SF_PATTERN:
gimp_pattern_select_widget_set (widget,
script->arg_defaults[i].sfa_pattern);
gimp_pattern_select_button_set_pattern_name
(GIMP_PATTERN_SELECT_BUTTON (widget),
script->arg_defaults[i].sfa_pattern);
break;
case SF_GRADIENT:
gimp_gradient_select_widget_set (widget,
script->arg_defaults[i].sfa_gradient);
gimp_gradient_select_button_set_gradient_name
(GIMP_GRADIENT_SELECT_BUTTON (widget),
script->arg_defaults[i].sfa_gradient);
break;
case SF_BRUSH:
gimp_brush_select_widget_set (widget,
script->arg_defaults[i].sfa_brush.name,
script->arg_defaults[i].sfa_brush.opacity,
script->arg_defaults[i].sfa_brush.spacing,
script->arg_defaults[i].sfa_brush.paint_mode);
gimp_brush_select_button_set_brush
(GIMP_BRUSH_SELECT_BUTTON (widget),
script->arg_defaults[i].sfa_brush.name,
script->arg_defaults[i].sfa_brush.opacity,
script->arg_defaults[i].sfa_brush.spacing,
script->arg_defaults[i].sfa_brush.paint_mode);
break;
case SF_OPTION: