app/brush_select.h app/brush_select.c app/internal_procs.c

Tue Oct 20 23:20:40 BST 1998 Andy Thomas <alt@picnic.demon.co.uk>


	* app/brush_select.h
	* app/brush_select.c
	* app/internal_procs.c
	* app/gimpbrushlist.c
	* libgimp/Makefile.am
	* libgimp/gimpmenu.h
	* libgimp/gimpmenu.c
	* plug-ins/script-fu/scripts/3d-outline.scm
	* plug-ins/script-fu/scripts/test-sphere.scm
	* plug-ins/script-fu/scripts/trochoid.scm
	* plug-ins/script-fu/script-fu-enums.h
	* plug-ins/script-fu/script-fu-scripts.c
	* plug-ins/script-fu/script-fu.c

	New file libgimp/gimpbrushmneu.c.

	Brush dialog can now be fully controlled via the PDB. New widget (not
	true widget) type added to libgimpui (gimp_brush_select_widget()).
	Plugins should easily be able to control & select brushes. Script-fu
	updated to use new widget. See the test script for example.

	Started to change some of the scripts to use the new widget types.
This commit is contained in:
BST 1998 Andy Thomas 1998-10-20 22:36:52 +00:00 committed by Andy Thomas
parent 30ffe1bcbc
commit af5cdfbd58
18 changed files with 1363 additions and 20 deletions

View File

@ -1,3 +1,28 @@
Tue Oct 20 23:20:40 BST 1998 Andy Thomas <alt@picnic.demon.co.uk>
* app/brush_select.h
* app/brush_select.c
* app/internal_procs.c
* app/gimpbrushlist.c
* libgimp/Makefile.am
* libgimp/gimpmenu.h
* libgimp/gimpmenu.c
* plug-ins/script-fu/scripts/3d-outline.scm
* plug-ins/script-fu/scripts/test-sphere.scm
* plug-ins/script-fu/scripts/trochoid.scm
* plug-ins/script-fu/script-fu-enums.h
* plug-ins/script-fu/script-fu-scripts.c
* plug-ins/script-fu/script-fu.c
New file libgimp/gimpbrushmneu.c.
Brush dialog can now be fully controlled via the PDB. New widget (not
true widget) type added to libgimpui (gimp_brush_select_widget()).
Plugins should easily be able to control & select brushes. Script-fu
updated to use new widget. See the test script for example.
Started to change some of the scripts to use the new widget types.
1998-10-19 Christopher James Lahey <clahey@umich.edu> 1998-10-19 Christopher James Lahey <clahey@umich.edu>
* app/docindex.c: New Drag & Drop works now. * app/docindex.c: New Drag & Drop works now.

View File

@ -270,7 +270,8 @@ brush_select_new (gchar * title,
label = gtk_label_new (_("Mode:")); label = gtk_label_new (_("Mode:"));
gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2); gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2);
menu = create_paint_mode_menu (paint_mode_menu_callback,(gpointer)bsp); menu = create_paint_mode_menu (paint_mode_menu_callback,(gpointer)bsp);
option_menu = gtk_option_menu_new (); bsp->option_menu =
option_menu = gtk_option_menu_new ();
gtk_box_pack_start (GTK_BOX (util_box), option_menu, FALSE, FALSE, 2); gtk_box_pack_start (GTK_BOX (util_box), option_menu, FALSE, FALSE, 2);
gtk_widget_show (label); gtk_widget_show (label);
@ -284,7 +285,7 @@ brush_select_new (gchar * title,
label = gtk_label_new (_("Opacity:")); label = gtk_label_new (_("Opacity:"));
gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2); gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2);
bsp->opacity_data = bsp->opacity_data =
GTK_ADJUSTMENT (gtk_adjustment_new ((active)?init_opacity:100.0, 0.0, 100.0, 1.0, 1.0, 0.0)); GTK_ADJUSTMENT (gtk_adjustment_new ((active)?(init_opacity*100.0):100.0, 0.0, 100.0, 1.0, 1.0, 0.0));
slider = gtk_hscale_new (bsp->opacity_data); slider = gtk_hscale_new (bsp->opacity_data);
gtk_box_pack_start (GTK_BOX (util_box), slider, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (util_box), slider, TRUE, TRUE, 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
@ -1221,7 +1222,7 @@ brushes_popup_invoker (Argument *args)
gchar * name; gchar * name;
gchar * title; gchar * title;
gchar * initial_brush; gchar * initial_brush;
gdouble initial_opacity = 100.0; gdouble initial_opacity = 1.0;
gint initial_spacing = 20; gint initial_spacing = 20;
gint initial_mode = 0; gint initial_mode = 0;
ProcRecord *prec = NULL; ProcRecord *prec = NULL;
@ -1316,3 +1317,200 @@ ProcRecord brushes_popup_proc =
/* Exec method */ /* Exec method */
{ { brushes_popup_invoker } }, { { brushes_popup_invoker } },
}; };
static BrushSelectP
brush_get_brushselect(gchar *name)
{
GSList *list;
BrushSelectP bsp;
list = active_dialogs;
while (list)
{
bsp = (BrushSelectP) list->data;
list = list->next;
if(strcmp(name,bsp->callback_name) == 0)
{
return bsp;
}
}
return NULL;
}
static Argument *
brush_close_popup_invoker (Argument *args)
{
gchar * name;
ProcRecord *prec = NULL;
BrushSelectP bsp;
success = (name = (char *) args[0].value.pdb_pointer) != NULL;
/* Check the proc exists */
if(!success || (prec = procedural_db_lookup(name)) == NULL)
{
success = 0;
return procedural_db_return_args (&brushes_close_popup_proc, success);
}
bsp = brush_get_brushselect(name);
if(bsp)
{
active_dialogs = g_slist_remove(active_dialogs,bsp);
if (GTK_WIDGET_VISIBLE (bsp->shell))
gtk_widget_hide (bsp->shell);
/* Free memory if poping down dialog which is not the main one */
if(bsp != brush_select_dialog)
{
gtk_widget_destroy(bsp->shell);
brush_select_free(bsp);
}
}
else
{
success = FALSE;
}
return procedural_db_return_args (&brushes_close_popup_proc, success);
}
/* The procedure definition */
ProcArg brush_close_popup_in_args[] =
{
{ PDB_STRING,
"callback_PDB_entry_name",
N_("The name of the callback registered for this popup"),
},
};
ProcRecord brushes_close_popup_proc =
{
"gimp_brushes_close_popup",
N_("Popdown the Gimp brush selection"),
N_("This procedure closes an opened brush selection dialog"),
"Andy Thomas",
"Andy Thomas",
"1998",
PDB_INTERNAL,
/* Input arguments */
sizeof(brush_close_popup_in_args) / sizeof(brush_close_popup_in_args[0]),
brush_close_popup_in_args,
/* Output arguments */
0,
NULL,
/* Exec method */
{ { brush_close_popup_invoker } },
};
static Argument *
brush_set_popup_invoker (Argument *args)
{
gchar * pdbname;
gchar * brush_name;
ProcRecord *prec = NULL;
BrushSelectP bsp;
success = (pdbname = (char *) args[0].value.pdb_pointer) != NULL;
brush_name = (char *) args[1].value.pdb_pointer;
/* Check the proc exists */
if(!success || (prec = procedural_db_lookup(pdbname)) == NULL)
{
success = 0;
return procedural_db_return_args (&brushes_set_popup_proc, success);
}
bsp = brush_get_brushselect(pdbname);
if(bsp)
{
GimpBrushP active = gimp_brush_list_get_brush(brush_list,brush_name);
if(active)
{
/* Must alter the wigdets on screen as well */
bsp->brush = active;
brush_select_select (bsp, gimp_brush_list_get_brush_index(brush_list, active));
bsp->opacity_value = args[2].value.pdb_float;
bsp->spacing_value = args[3].value.pdb_int;
if(args[4].value.pdb_int >= 0 && args[4].value.pdb_int <= VALUE_MODE)
bsp->paint_mode = args[4].value.pdb_int;
bsp->spacing_data->value = bsp->spacing_value;
gtk_signal_emit_by_name (GTK_OBJECT (bsp->spacing_data), "value_changed");
bsp->opacity_data->value = bsp->opacity_value * 100.0;
gtk_signal_emit_by_name (GTK_OBJECT (bsp->opacity_data), "value_changed");
gtk_option_menu_set_history(GTK_OPTION_MENU(bsp->option_menu),bsp->paint_mode);
/* Can alter active_dialogs list*/
success = TRUE;
}
}
else
{
success = FALSE;
}
return procedural_db_return_args (&brushes_set_popup_proc, success);
}
/* The procedure definition */
ProcArg brush_set_popup_in_args[] =
{
{ PDB_STRING,
"callback_PDB_entry_name",
N_("The name of the callback registered for this popup"),
},
{ PDB_STRING,
"brushname",
N_("The name of the brush to set as selected"),
},
{ PDB_FLOAT,
"opacity",
N_("The initial opacity of the brush"),
},
{ PDB_INT32,
"spacing",
N_("The initial spacing of the brush (if < 0 then use brush default spacing)"),
},
{ PDB_INT32,
"initial paint mode",
N_("The initial paint mode: { NORMAL (0), DISSOLVE (1), BEHIND (2), MULTIPLY/BURN (3), SCREEN (4), OVERLAY (5) DIFFERENCE (6), ADDITION (7), SUBTRACT (8), DARKEN-ONLY (9), LIGHTEN-ONLY (10), HUE (11), SATURATION (12), COLOR (13), VALUE (14), DIVIDE/DODGE (15) }"),
},
};
ProcRecord brushes_set_popup_proc =
{
"gimp_brushes_set_popup",
N_("Sets the current brush selection in a popup"),
N_("Sets the current brush selection in a popup"),
"Andy Thomas",
"Andy Thomas",
"1998",
PDB_INTERNAL,
/* Input arguments */
sizeof(brush_set_popup_in_args) / sizeof(brush_set_popup_in_args[0]),
brush_set_popup_in_args,
/* Output arguments */
0,
NULL,
/* Exec method */
{ { brush_set_popup_invoker } },
};

View File

@ -35,6 +35,7 @@ struct _BrushSelect {
GtkAdjustment *spacing_data; GtkAdjustment *spacing_data;
GtkAdjustment *sbar_data; GtkAdjustment *sbar_data;
GtkWidget *edit_button; GtkWidget *edit_button;
GtkWidget *option_menu;
int width, height; int width, height;
int cell_width, cell_height; int cell_width, cell_height;
int scroll_offset; int scroll_offset;
@ -74,5 +75,8 @@ GtkWidget * create_paint_mode_menu (MenuItemCallback, gpointer);
/* PDB entry */ /* PDB entry */
extern ProcRecord brushes_popup_proc; extern ProcRecord brushes_popup_proc;
extern ProcRecord brushes_close_popup_proc;
extern ProcRecord brushes_set_popup_proc;
extern ProcRecord brushes_get_brush_data_proc;
#endif /* __BRUSH_SELECT_H__ */ #endif /* __BRUSH_SELECT_H__ */

View File

@ -988,3 +988,126 @@ ProcRecord brushes_list_proc =
/* Exec method */ /* Exec method */
{ { brushes_list_invoker } }, { { brushes_list_invoker } },
}; };
/*******************************/
/* BRUSHES_GET_BRUSH_DATA */
static Argument *
brushes_get_brush_data_invoker (Argument *args)
{
GimpBrushP brushp = NULL;
GSList *list;
char *name;
static Argument *return_args;
success = (name = (char *) args[0].value.pdb_pointer) != NULL;
if (!success)
{
/* No name use active pattern */
success = (brushp = get_active_brush ()) != NULL;
}
else
{
list = GIMP_LIST(brush_list)->list;
success = FALSE;
while (list)
{
brushp = (GimpBrushP) list->data;
if (!strcmp (brushp->name, name))
{
success = TRUE;
break;
}
list = g_slist_next (list);
}
}
return_args = procedural_db_return_args (&brushes_get_brush_data_proc, success);
if (success)
{
return_args[1].value.pdb_pointer = g_strdup (brushp->name);
return_args[2].value.pdb_float = 1.0; /*opacity_value;*/
return_args[3].value.pdb_int = brushp->spacing;
return_args[4].value.pdb_int = 0; /* paint_mode; */
return_args[5].value.pdb_int = brushp->mask->width;
return_args[6].value.pdb_int = brushp->mask->height;
return_args[7].value.pdb_int = brushp->mask->height*brushp->mask->width;
return_args[8].value.pdb_pointer = g_malloc(return_args[7].value.pdb_int);
g_memmove(return_args[8].value.pdb_pointer,
temp_buf_data (brushp->mask),
return_args[7].value.pdb_int);
}
return return_args;
}
/* The procedure definition */
ProcArg brushes_get_brush_data_in_args[] =
{
{ PDB_STRING,
"name",
"the brush name (\"\" means current active pattern) "
}
};
ProcArg brushes_get_brush_data_out_args[] =
{
{ PDB_STRING,
"name",
"the brush name"
},
{ PDB_FLOAT,
"opacity",
"the brush opacity"
},
{ PDB_INT32,
"spacing",
"the brush spacing"
},
{ PDB_INT32,
"paint_mode",
"the brush paint mode"
},
{ PDB_INT32,
"width",
"the brush width"
},
{ PDB_INT32,
"height",
"the brush height"
},
{ PDB_INT32,
"length",
"length of brush mask data"},
{ PDB_INT8ARRAY,
"mask_data",
"the brush mask data"},
};
ProcRecord brushes_get_brush_data_proc =
{
"gimp_brushes_get_brush_data",
"Retrieve information about the currently active brush (including data)",
"This procedure retrieves information about the currently active brush. This includes the brush name, and the brush extents (width and height). It also returns the brush data",
"Andy Thomas",
"Andy Thomas",
"1998",
PDB_INTERNAL,
/* Input arguments */
sizeof(brushes_get_brush_data_in_args) / sizeof(brushes_get_brush_data_in_args[0]),
brushes_get_brush_data_in_args,
/* Output arguments */
sizeof(brushes_get_brush_data_out_args) / sizeof(brushes_get_brush_data_out_args[0]),
brushes_get_brush_data_out_args,
/* Exec method */
{ { brushes_get_brush_data_invoker } },
};

View File

@ -270,7 +270,8 @@ brush_select_new (gchar * title,
label = gtk_label_new (_("Mode:")); label = gtk_label_new (_("Mode:"));
gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2); gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2);
menu = create_paint_mode_menu (paint_mode_menu_callback,(gpointer)bsp); menu = create_paint_mode_menu (paint_mode_menu_callback,(gpointer)bsp);
option_menu = gtk_option_menu_new (); bsp->option_menu =
option_menu = gtk_option_menu_new ();
gtk_box_pack_start (GTK_BOX (util_box), option_menu, FALSE, FALSE, 2); gtk_box_pack_start (GTK_BOX (util_box), option_menu, FALSE, FALSE, 2);
gtk_widget_show (label); gtk_widget_show (label);
@ -284,7 +285,7 @@ brush_select_new (gchar * title,
label = gtk_label_new (_("Opacity:")); label = gtk_label_new (_("Opacity:"));
gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2); gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2);
bsp->opacity_data = bsp->opacity_data =
GTK_ADJUSTMENT (gtk_adjustment_new ((active)?init_opacity:100.0, 0.0, 100.0, 1.0, 1.0, 0.0)); GTK_ADJUSTMENT (gtk_adjustment_new ((active)?(init_opacity*100.0):100.0, 0.0, 100.0, 1.0, 1.0, 0.0));
slider = gtk_hscale_new (bsp->opacity_data); slider = gtk_hscale_new (bsp->opacity_data);
gtk_box_pack_start (GTK_BOX (util_box), slider, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (util_box), slider, TRUE, TRUE, 0);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP); gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
@ -1221,7 +1222,7 @@ brushes_popup_invoker (Argument *args)
gchar * name; gchar * name;
gchar * title; gchar * title;
gchar * initial_brush; gchar * initial_brush;
gdouble initial_opacity = 100.0; gdouble initial_opacity = 1.0;
gint initial_spacing = 20; gint initial_spacing = 20;
gint initial_mode = 0; gint initial_mode = 0;
ProcRecord *prec = NULL; ProcRecord *prec = NULL;
@ -1316,3 +1317,200 @@ ProcRecord brushes_popup_proc =
/* Exec method */ /* Exec method */
{ { brushes_popup_invoker } }, { { brushes_popup_invoker } },
}; };
static BrushSelectP
brush_get_brushselect(gchar *name)
{
GSList *list;
BrushSelectP bsp;
list = active_dialogs;
while (list)
{
bsp = (BrushSelectP) list->data;
list = list->next;
if(strcmp(name,bsp->callback_name) == 0)
{
return bsp;
}
}
return NULL;
}
static Argument *
brush_close_popup_invoker (Argument *args)
{
gchar * name;
ProcRecord *prec = NULL;
BrushSelectP bsp;
success = (name = (char *) args[0].value.pdb_pointer) != NULL;
/* Check the proc exists */
if(!success || (prec = procedural_db_lookup(name)) == NULL)
{
success = 0;
return procedural_db_return_args (&brushes_close_popup_proc, success);
}
bsp = brush_get_brushselect(name);
if(bsp)
{
active_dialogs = g_slist_remove(active_dialogs,bsp);
if (GTK_WIDGET_VISIBLE (bsp->shell))
gtk_widget_hide (bsp->shell);
/* Free memory if poping down dialog which is not the main one */
if(bsp != brush_select_dialog)
{
gtk_widget_destroy(bsp->shell);
brush_select_free(bsp);
}
}
else
{
success = FALSE;
}
return procedural_db_return_args (&brushes_close_popup_proc, success);
}
/* The procedure definition */
ProcArg brush_close_popup_in_args[] =
{
{ PDB_STRING,
"callback_PDB_entry_name",
N_("The name of the callback registered for this popup"),
},
};
ProcRecord brushes_close_popup_proc =
{
"gimp_brushes_close_popup",
N_("Popdown the Gimp brush selection"),
N_("This procedure closes an opened brush selection dialog"),
"Andy Thomas",
"Andy Thomas",
"1998",
PDB_INTERNAL,
/* Input arguments */
sizeof(brush_close_popup_in_args) / sizeof(brush_close_popup_in_args[0]),
brush_close_popup_in_args,
/* Output arguments */
0,
NULL,
/* Exec method */
{ { brush_close_popup_invoker } },
};
static Argument *
brush_set_popup_invoker (Argument *args)
{
gchar * pdbname;
gchar * brush_name;
ProcRecord *prec = NULL;
BrushSelectP bsp;
success = (pdbname = (char *) args[0].value.pdb_pointer) != NULL;
brush_name = (char *) args[1].value.pdb_pointer;
/* Check the proc exists */
if(!success || (prec = procedural_db_lookup(pdbname)) == NULL)
{
success = 0;
return procedural_db_return_args (&brushes_set_popup_proc, success);
}
bsp = brush_get_brushselect(pdbname);
if(bsp)
{
GimpBrushP active = gimp_brush_list_get_brush(brush_list,brush_name);
if(active)
{
/* Must alter the wigdets on screen as well */
bsp->brush = active;
brush_select_select (bsp, gimp_brush_list_get_brush_index(brush_list, active));
bsp->opacity_value = args[2].value.pdb_float;
bsp->spacing_value = args[3].value.pdb_int;
if(args[4].value.pdb_int >= 0 && args[4].value.pdb_int <= VALUE_MODE)
bsp->paint_mode = args[4].value.pdb_int;
bsp->spacing_data->value = bsp->spacing_value;
gtk_signal_emit_by_name (GTK_OBJECT (bsp->spacing_data), "value_changed");
bsp->opacity_data->value = bsp->opacity_value * 100.0;
gtk_signal_emit_by_name (GTK_OBJECT (bsp->opacity_data), "value_changed");
gtk_option_menu_set_history(GTK_OPTION_MENU(bsp->option_menu),bsp->paint_mode);
/* Can alter active_dialogs list*/
success = TRUE;
}
}
else
{
success = FALSE;
}
return procedural_db_return_args (&brushes_set_popup_proc, success);
}
/* The procedure definition */
ProcArg brush_set_popup_in_args[] =
{
{ PDB_STRING,
"callback_PDB_entry_name",
N_("The name of the callback registered for this popup"),
},
{ PDB_STRING,
"brushname",
N_("The name of the brush to set as selected"),
},
{ PDB_FLOAT,
"opacity",
N_("The initial opacity of the brush"),
},
{ PDB_INT32,
"spacing",
N_("The initial spacing of the brush (if < 0 then use brush default spacing)"),
},
{ PDB_INT32,
"initial paint mode",
N_("The initial paint mode: { NORMAL (0), DISSOLVE (1), BEHIND (2), MULTIPLY/BURN (3), SCREEN (4), OVERLAY (5) DIFFERENCE (6), ADDITION (7), SUBTRACT (8), DARKEN-ONLY (9), LIGHTEN-ONLY (10), HUE (11), SATURATION (12), COLOR (13), VALUE (14), DIVIDE/DODGE (15) }"),
},
};
ProcRecord brushes_set_popup_proc =
{
"gimp_brushes_set_popup",
N_("Sets the current brush selection in a popup"),
N_("Sets the current brush selection in a popup"),
"Andy Thomas",
"Andy Thomas",
"1998",
PDB_INTERNAL,
/* Input arguments */
sizeof(brush_set_popup_in_args) / sizeof(brush_set_popup_in_args[0]),
brush_set_popup_in_args,
/* Output arguments */
0,
NULL,
/* Exec method */
{ { brush_set_popup_invoker } },
};

View File

@ -35,6 +35,7 @@ struct _BrushSelect {
GtkAdjustment *spacing_data; GtkAdjustment *spacing_data;
GtkAdjustment *sbar_data; GtkAdjustment *sbar_data;
GtkWidget *edit_button; GtkWidget *edit_button;
GtkWidget *option_menu;
int width, height; int width, height;
int cell_width, cell_height; int cell_width, cell_height;
int scroll_offset; int scroll_offset;
@ -74,5 +75,8 @@ GtkWidget * create_paint_mode_menu (MenuItemCallback, gpointer);
/* PDB entry */ /* PDB entry */
extern ProcRecord brushes_popup_proc; extern ProcRecord brushes_popup_proc;
extern ProcRecord brushes_close_popup_proc;
extern ProcRecord brushes_set_popup_proc;
extern ProcRecord brushes_get_brush_data_proc;
#endif /* __BRUSH_SELECT_H__ */ #endif /* __BRUSH_SELECT_H__ */

View File

@ -80,7 +80,7 @@ internal_procs_init ()
{ {
gfloat pcount = 0; gfloat pcount = 0;
/* grep -c procedural_db_register internal_procs.c */ /* grep -c procedural_db_register internal_procs.c */
gfloat total_pcount = 237; gfloat total_pcount = 240;
app_init_update_status("Internal Procedures", "Tool procedures", app_init_update_status("Internal Procedures", "Tool procedures",
pcount/total_pcount); pcount/total_pcount);
@ -338,6 +338,9 @@ internal_procs_init ()
procedural_db_register (&brushes_set_paint_mode_proc); pcount++; procedural_db_register (&brushes_set_paint_mode_proc); pcount++;
procedural_db_register (&brushes_list_proc); pcount++; procedural_db_register (&brushes_list_proc); pcount++;
procedural_db_register (&brushes_popup_proc); pcount++; procedural_db_register (&brushes_popup_proc); pcount++;
procedural_db_register (&brushes_close_popup_proc); pcount++;
procedural_db_register (&brushes_set_popup_proc); pcount++;
procedural_db_register (&brushes_get_brush_data_proc); pcount++;
procedural_db_register (&patterns_get_pattern_proc); pcount++; procedural_db_register (&patterns_get_pattern_proc); pcount++;
procedural_db_register (&patterns_set_pattern_proc); pcount++; procedural_db_register (&patterns_set_pattern_proc); pcount++;
procedural_db_register (&patterns_list_proc); pcount++; procedural_db_register (&patterns_list_proc); pcount++;

View File

@ -48,6 +48,7 @@ libgimp_la_SOURCES = \
libgimpui_la_SOURCES = \ libgimpui_la_SOURCES = \
gimpmenu.c \ gimpmenu.c \
gimpbrushmenu.c \
gimppatternmenu.c gimppatternmenu.c
gimpinclude_HEADERS = \ gimpinclude_HEADERS = \

445
libgimp/gimpbrushmenu.c Normal file
View File

@ -0,0 +1,445 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
* Copyright (C) 1998 Andy Thomas
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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 Library 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 <stdio.h>
#include <string.h>
#include "gimp.h"
#include "gimpui.h"
/* Idea is to have a function to call that returns a widget that
* completely controls the selection of a brush.
* you get a widget returned that you can use in a table say.
* In:- Initial brush name. Null means use current selection.
* pointer to func to call when brush changes (GRunBrushCallback).
* Returned:- Pointer to a widget that you can use in UI.
*
* Widget simply made up of a preview widget (20x20) containing the brush mask
* and a button that can be clicked on to change the brush.
*/
#define BSEL_DATA_KEY "__bsel_data"
#define CELL_SIZE 20
#define BRUSH_EVENT_MASK GDK_EXPOSURE_MASK | \
GDK_BUTTON_PRESS_MASK | \
GDK_BUTTON_RELEASE_MASK | \
GDK_BUTTON1_MOTION_MASK
struct __brushes_sel {
gchar * dname;
GRunBrushCallback cback;
GtkWidget *brush_preview;
GtkWidget *device_brushpopup;
GtkWidget *device_brushpreview;
GtkWidget *button;
GtkWidget *top_hbox;
gchar *brush_name; /* Local copy */
gdouble opacity;
gint spacing;
gint paint_mode;
gint width;
gint height;
gchar *mask_data; /* local copy */
void *brush_popup_pnt; /* POinter use to control the popup */
gpointer udata;
};
typedef struct __brushes_sel BSelect, * BSelectP;
static void
brush_popup_open (int x,
int y,
BSelectP bsel)
{
gint x_org, y_org;
gint scr_w, scr_h;
gchar *src, *buf;
unsigned char *b,*s;
/* make sure the popup exists and is not visible */
if (bsel->device_brushpopup == NULL)
{
GtkWidget *frame;
bsel->device_brushpopup = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_policy (GTK_WINDOW (bsel->device_brushpopup), FALSE, FALSE, TRUE);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (bsel->device_brushpopup), frame);
gtk_widget_show (frame);
bsel->device_brushpreview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
gtk_container_add (GTK_CONTAINER (frame), bsel->device_brushpreview);
gtk_widget_show (bsel->device_brushpreview);
}
else
{
gtk_widget_hide (bsel->device_brushpopup);
}
/* decide where to put the popup */
gdk_window_get_origin (bsel->brush_preview->window, &x_org, &y_org);
scr_w = gdk_screen_width ();
scr_h = gdk_screen_height ();
x = x_org + x - (bsel->width >> 1);
y = y_org + y - (bsel->height >> 1);
x = (x < 0) ? 0 : x;
y = (y < 0) ? 0 : y;
x = (x + bsel->width > scr_w) ? scr_w - bsel->width : x;
y = (y + bsel->height > scr_h) ? scr_h - bsel->height : y;
gtk_preview_size (GTK_PREVIEW (bsel->device_brushpreview), bsel->width, bsel->height);
gtk_widget_popup (bsel->device_brushpopup, x, y);
/* Draw the brush */
buf = g_new (gchar, bsel->width);
memset(buf, 255, sizeof(bsel->width));
/* for (i = 0; i < CELL_SIZE; i++) */
/* gtk_preview_draw_row (GTK_PREVIEW(bsel->device_brushpreview), (guchar *)buf, 0, i, CELL_SIZE); */
src = bsel->mask_data;
for (y = 0; y < bsel->height; y++)
{
int j;
s = src;
b = buf;
for (j = 0; j < bsel->width ; j++)
*b++ = 255 - *s++;
gtk_preview_draw_row (GTK_PREVIEW (bsel->device_brushpreview), (guchar *)buf, 0, y, bsel->width);
src += bsel->width;
}
g_free(buf);
/* Draw the brush preview */
gtk_widget_draw (bsel->device_brushpreview, NULL);
}
static void
brush_popup_close (BSelectP bsel)
{
if (bsel->device_brushpopup != NULL)
gtk_widget_hide (bsel->device_brushpopup);
}
static gint
brush_preview_events (GtkWidget *widget,
GdkEvent *event,
gpointer udata)
{
GdkEventButton *bevent;
BSelectP bsel = (BSelectP)udata;
if(bsel->mask_data)
{
switch (event->type)
{
case GDK_EXPOSE:
break;
case GDK_BUTTON_PRESS:
bevent = (GdkEventButton *) event;
if (bevent->button == 1)
{
brush_popup_open (bevent->x, bevent->y, bsel);
}
break;
case GDK_BUTTON_RELEASE:
bevent = (GdkEventButton *) event;
if (bevent->button == 1)
{
/* Ungrab the pointer */
gdk_pointer_ungrab (bevent->time);
/* Close the device preview popup window */
brush_popup_close (bsel);
}
break;
case GDK_DELETE:
break;
default:
break;
}
}
return FALSE;
}
static void
brush_pre_update(GtkWidget *brush_preview,
gint brush_width,
gint brush_height,
gchar *mask_data)
{
gint y,i;
gchar *src, *buf;
unsigned char *b,*s;
int offset_x, offset_y;
int yend;
int ystart;
gint width,height;
/* Draw the brush */
buf = g_new (gchar, CELL_SIZE);
/* Limit to cell size */
width = (brush_width > CELL_SIZE) ? CELL_SIZE: brush_width;
height = (brush_height > CELL_SIZE) ? CELL_SIZE: brush_height;
/* Set buffer to white */
memset(buf, 255, CELL_SIZE);
for (i = 0; i < CELL_SIZE; i++)
gtk_preview_draw_row (GTK_PREVIEW(brush_preview), (guchar *)buf, 0, i, CELL_SIZE);
offset_x = ((CELL_SIZE - width) >> 1);
offset_y = ((CELL_SIZE - height) >> 1);
ystart = CLAMP (offset_y, 0, CELL_SIZE);
yend = CLAMP (offset_y + height, 0, CELL_SIZE);
src = mask_data;
for (y = ystart; y < yend; y++)
{
int j;
s = src;
b = buf;
for (j = 0; j < width ; j++)
*b++ = 255 - *s++;
gtk_preview_draw_row (GTK_PREVIEW (brush_preview), (guchar *)buf, offset_x, y, width);
src += brush_width;
}
g_free(buf);
/* Draw the brush preview */
gtk_widget_draw (brush_preview, NULL);
}
static void
brush_select_invoker(gchar *name,
gdouble opacity,
gint spacing,
gint paint_mode,
gint width,
gint height,
gchar * mask_data,
gint closing,
gpointer udata)
{
gint mask_d_sz;
BSelectP bsel = (BSelectP)udata;
if(bsel->mask_data != NULL)
g_free(bsel->mask_data);
bsel->width = width;
bsel->height = height;
mask_d_sz = width*height;
bsel->mask_data = g_malloc(mask_d_sz);
g_memmove(bsel->mask_data,mask_data,mask_d_sz);
brush_pre_update(bsel->brush_preview,bsel->width,bsel->height,bsel->mask_data);
bsel->opacity = opacity;
bsel->spacing = spacing;
bsel->paint_mode = paint_mode;
if(bsel->cback != NULL)
(bsel->cback)(name,opacity,spacing,paint_mode,width,height,mask_data,closing,bsel->udata);
if(closing)
{
gtk_widget_set_sensitive(bsel->button,TRUE);
bsel->brush_popup_pnt = NULL;
}
}
static void
brush_select_callback (GtkWidget *widget,
gpointer data)
{
BSelectP bsel = (BSelectP)data;
gtk_widget_set_sensitive(bsel->button,FALSE);
bsel->brush_popup_pnt =
gimp_interactive_selection_brush((bsel->dname)?bsel->dname:"Brush Plugin Selection",
bsel->brush_name,
bsel->opacity,
bsel->spacing,
bsel->paint_mode,
brush_select_invoker,bsel);
}
GtkWidget *
gimp_brush_select_widget(gchar *dname,
gchar *ibrush,
gdouble opacity,
gint spacing,
gint paint_mode,
GRunBrushCallback cback,
gpointer udata)
{
GtkWidget * frame;
GtkWidget * hbox;
GtkWidget * brush;
GtkWidget * button;
gint width,height;
gint init_spacing,init_paint_mode;
gdouble init_opacity;
gchar *mask_data;
gchar *brush_name;
BSelectP bsel = g_new(BSelect, sizeof(BSelect));
hbox = gtk_hbox_new (FALSE, 3);
gtk_widget_show(hbox);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_OUT);
gtk_widget_show(frame);
brush = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
gtk_preview_size (GTK_PREVIEW (brush), CELL_SIZE, CELL_SIZE);
gtk_widget_show(brush);
gtk_container_add (GTK_CONTAINER (frame),brush);
gtk_widget_set_events (brush, BRUSH_EVENT_MASK);
gtk_signal_connect (GTK_OBJECT (brush), "event",
(GtkSignalFunc) brush_preview_events,
(gpointer)bsel);
bsel->cback = cback;
bsel->udata = udata;
bsel->mask_data = NULL;
bsel->device_brushpopup = bsel->device_brushpreview = NULL;
bsel->brush_preview = brush;
bsel->brush_name = ibrush;
bsel->dname = dname;
bsel->brush_popup_pnt = NULL;
/* Do initial brush setup */
brush_name = gimp_brushes_get_brush_data(ibrush,
&init_opacity,
&init_spacing,
&init_paint_mode,
&width,
&height,
&mask_data);
if(brush_name)
{
brush_pre_update(bsel->brush_preview,width,height,mask_data);
bsel->mask_data = mask_data;
bsel->brush_name = brush_name;
bsel->width = width;
bsel->height = height;
if(opacity != -1)
bsel->opacity = opacity;
else
bsel->opacity = init_opacity;
if(spacing != -1)
bsel->spacing = spacing;
else
bsel->spacing = init_spacing;
if(paint_mode != -1)
bsel->paint_mode = paint_mode;
else
bsel->paint_mode = init_paint_mode;
}
gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
button = gtk_button_new_with_label ("... ");
gtk_container_add (GTK_CONTAINER (hbox), button);
gtk_widget_show(button);
bsel->button = button;
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) brush_select_callback,
(gpointer)bsel);
gtk_object_set_data(GTK_OBJECT(hbox),BSEL_DATA_KEY,(gpointer)bsel);
return hbox;
}
gint
gimp_brush_select_widget_close_popup(GtkWidget *w)
{
gint ret_val = FALSE;
BSelectP bsel = (BSelectP)gtk_object_get_data(GTK_OBJECT(w),BSEL_DATA_KEY);
if(bsel && bsel->brush_popup_pnt)
{
ret_val = gimp_brush_close_popup(bsel->brush_popup_pnt);
bsel->brush_popup_pnt = NULL;
}
return ret_val;
}
gint
gimp_brush_select_widget_set_popup(GtkWidget *w,
gchar *bname,
gdouble opacity,
gint spacing,
gint paint_mode)
{
gint ret_val = FALSE;
gint width,height;
gint init_spacing,init_paint_mode;
gdouble init_opacity;
gchar *mask_data;
gchar *brush_name;
BSelectP bsel = (BSelectP)gtk_object_get_data(GTK_OBJECT(w),BSEL_DATA_KEY);
if(bsel)
{
brush_name = gimp_brushes_get_brush_data(bname,
&init_opacity,
&init_spacing,
&init_paint_mode,
&width,&height,&mask_data);
if(opacity == -1.0)
opacity = init_opacity;
if(spacing == -1)
spacing = init_spacing;
if(paint_mode == -1)
paint_mode = init_paint_mode;
brush_select_invoker(bname,opacity,spacing,paint_mode,width,height,mask_data,0,bsel);
if(bsel->brush_popup_pnt)
{
if(gimp_brush_set_popup(bsel->brush_popup_pnt,bname,opacity,spacing,paint_mode))
{
ret_val = TRUE;
}
}
}
return ret_val;
}

View File

@ -643,9 +643,12 @@ gen_temp_plugin_name (void)
/* Can only be used in conjuction with gdk since we need to tie into the input /* Can only be used in conjuction with gdk since we need to tie into the input
* selection mech. * selection mech.
*/ */
void void *
gimp_interactive_selection_brush(gchar *dialogname, gimp_interactive_selection_brush(gchar *dialogname,
gchar *brush_name, gchar *brush_name,
gdouble opacity,
gint spacing,
gint paint_mode,
GRunBrushCallback callback, GRunBrushCallback callback,
gpointer udata) gpointer udata)
{ {
@ -688,9 +691,9 @@ gimp_interactive_selection_brush(gchar *dialogname,
PARAM_STRING,pdbname, PARAM_STRING,pdbname,
PARAM_STRING,dialogname, PARAM_STRING,dialogname,
PARAM_STRING,brush_name,/*name*/ PARAM_STRING,brush_name,/*name*/
PARAM_FLOAT, 1.0, /*Opacity*/ PARAM_FLOAT, opacity, /*Opacity*/
PARAM_INT32, -1, /*default spacing*/ PARAM_INT32, spacing, /*default spacing*/
PARAM_INT32, 0, /*paint mode*/ PARAM_INT32, paint_mode, /*paint mode*/
PARAM_END); PARAM_END);
/* if (pdbreturn_vals[0].data.d_status != STATUS_SUCCESS) */ /* if (pdbreturn_vals[0].data.d_status != STATUS_SUCCESS) */
@ -714,9 +717,94 @@ gimp_interactive_selection_brush(gchar *dialogname,
bdata->callback = callback; bdata->callback = callback;
bdata->udata = udata; bdata->udata = udata;
g_hash_table_insert(gbrush_ht,pdbname,bdata); g_hash_table_insert(gbrush_ht,pdbname,bdata);
return pdbname;
} }
gchar *
gimp_brushes_get_brush_data (gchar *bname,
gdouble *opacity,
gint *spacing,
gint *paint_mode,
gint *width,
gint *height,
gchar **mask_data)
{
GParam *return_vals;
int nreturn_vals;
gchar *ret_name = NULL;
return_vals = gimp_run_procedure ("gimp_brushes_get_brush_data",
&nreturn_vals,
PARAM_STRING, bname,
PARAM_END);
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
ret_name = g_strdup(return_vals[1].data.d_string);
*opacity = return_vals[2].data.d_float;
*spacing = return_vals[3].data.d_int32;
*paint_mode = return_vals[4].data.d_int32;
*width = return_vals[5].data.d_int32;
*height = return_vals[6].data.d_int32;
*mask_data = g_new (gchar,return_vals[7].data.d_int32);
g_memmove (*mask_data, return_vals[8].data.d_int32array,return_vals[7].data.d_int32);
}
gimp_destroy_params (return_vals, nreturn_vals);
return ret_name;
}
gint
gimp_brush_close_popup(void * popup_pnt)
{
GParam *return_vals;
int nreturn_vals;
gint retval;
return_vals = gimp_run_procedure ("gimp_brushes_close_popup",
&nreturn_vals,
PARAM_STRING, popup_pnt,
PARAM_END);
gimp_destroy_params (return_vals, nreturn_vals);
retval = (return_vals[0].data.d_status == STATUS_SUCCESS);
return retval;
}
gint
gimp_brush_set_popup(void * popup_pnt,
gchar * pname,
gdouble opacity,
gint spacing,
gint paint_mode)
{
GParam *return_vals;
int nreturn_vals;
gint retval;
return_vals = gimp_run_procedure ("gimp_brushes_set_popup",
&nreturn_vals,
PARAM_STRING, popup_pnt,
PARAM_STRING, pname,
PARAM_FLOAT, opacity,
PARAM_INT32, spacing,
PARAM_INT32, paint_mode,
PARAM_END);
gimp_destroy_params (return_vals, nreturn_vals);
retval = (return_vals[0].data.d_status == STATUS_SUCCESS);
return retval;
}
void * void *
gimp_interactive_selection_pattern(gchar *dialogname, gimp_interactive_selection_pattern(gchar *dialogname,
gchar *pattern_name, gchar *pattern_name,

View File

@ -71,11 +71,46 @@ GtkWidget* gimp_drawable_menu_new (GimpConstraintFunc constraint,
gpointer data, gpointer data,
gint32 active_drawable); gint32 active_drawable);
void gimp_interactive_selection_brush (gchar *dialogname, void * gimp_interactive_selection_brush (gchar *dialogname,
gchar *brush_name, gchar *brush_name,
gdouble opacity,
gint spacing,
gint paint_mode,
GRunBrushCallback callback, GRunBrushCallback callback,
gpointer udata); gpointer udata);
GtkWidget * gimp_brush_select_widget(gchar * dname,
gchar * ibrush,
gdouble opacity,
gint spacing,
gint paint_mode,
GRunBrushCallback cback,
gpointer);
gint gimp_brush_select_widget_close_popup(GtkWidget *w);
gint gimp_brush_select_widget_set_popup(GtkWidget *w,
gchar *pname,
gdouble opacity,
gint spacing,
gint paint_mode);
gchar *gimp_brushes_get_brush_data (gchar *pname,
gdouble *opacity,
gint *spacing,
gint *paint_mode,
gint *width,
gint *height,
gchar **mask_data);
gint gimp_brush_set_popup(void * popup_pnt,
gchar * pname,
gdouble opacity,
gint spacing,
gint paint_mode);
gint gimp_brush_close_popup(void * popup_pnt);
void * gimp_interactive_selection_pattern (gchar *dialogtitle, void * gimp_interactive_selection_pattern (gchar *dialogtitle,
gchar *pattern_name, gchar *pattern_name,
GRunPatternCallback callback, GRunPatternCallback callback,

View File

@ -33,7 +33,8 @@ typedef enum
SF_STRING, SF_STRING,
SF_ADJUSTMENT, SF_ADJUSTMENT,
SF_FONT, SF_FONT,
SF_PATTERN SF_PATTERN,
SF_BRUSH
} SFArgType; } SFArgType;
typedef enum typedef enum

View File

@ -68,6 +68,15 @@ typedef struct
gchar *fontname; gchar *fontname;
} SFFont; } SFFont;
typedef struct
{
gchar *name;
gdouble opacity;
gint spacing;
gint paint_mode;
} SFBrush;
typedef union typedef union
{ {
gint32 sfa_image; gint32 sfa_image;
@ -80,6 +89,7 @@ typedef union
SFAdjustment sfa_adjustment; SFAdjustment sfa_adjustment;
SFFont sfa_font; SFFont sfa_font;
gchar * sfa_pattern; gchar * sfa_pattern;
SFBrush sfa_brush;
} SFArgValue; } SFArgValue;
typedef struct typedef struct
@ -175,6 +185,15 @@ static void script_fu_pattern_preview (gchar *name,
gint closing, gint closing,
gpointer udata); gpointer udata);
static void script_fu_brush_preview (char *, /* Name */
gdouble, /* opacity */
gint, /* spacing */
gint, /* paint_mode */
gint, /* width */
gint, /* height */
gchar *, /* mask data */
gint, /* dialog closing */
gpointer /* user data */);
@ -339,6 +358,7 @@ script_fu_add_script (LISP a)
gdouble color[3]; gdouble color[3];
LISP color_list; LISP color_list;
LISP adj_list; LISP adj_list;
LISP brush_list;
gchar *menu_path = NULL; gchar *menu_path = NULL;
/* Check the length of a */ /* Check the length of a */
@ -572,8 +592,30 @@ script_fu_add_script (LISP a)
args[i + 1].description = script->arg_labels[i]; args[i + 1].description = script->arg_labels[i];
break; break;
case SF_BRUSH:
if (!TYPEP (car (a), tc_cons))
return my_err ("script-fu-register: brush defaults must be a list", NIL);
brush_list = car (a);
script->arg_defaults[i].sfa_brush.name = g_strdup (get_c_string (car (brush_list)));
brush_list = cdr (brush_list);
script->arg_defaults[i].sfa_brush.opacity = get_c_double (car (brush_list));
brush_list = cdr (brush_list);
script->arg_defaults[i].sfa_brush.spacing = get_c_long (car (brush_list));
brush_list = cdr (brush_list);
script->arg_defaults[i].sfa_brush.paint_mode = get_c_long (car (brush_list));
script->arg_values[i].sfa_brush = script->arg_defaults[i].sfa_brush;
/* Need this since we need a copy of the string
* in the values area. We could free it later but the
* default one must hang around.
*/
script->arg_values[i].sfa_brush.name = g_strdup(script->arg_defaults[i].sfa_brush.name);
args[i + 1].type = PARAM_STRING;
args[i + 1].name = "brush";
args[i + 1].description = script->arg_labels[i];
break; break;
default: default:
break; break;
} }
@ -725,6 +767,9 @@ script_fu_script_proc (char *name,
case SF_PATTERN: case SF_PATTERN:
length += strlen (params[i + 1].data.d_string) + 3; length += strlen (params[i + 1].data.d_string) + 3;
break; break;
case SF_BRUSH:
length += strlen (params[i + 1].data.d_string) + 3;
break;
default: default:
break; break;
} }
@ -775,6 +820,10 @@ script_fu_script_proc (char *name,
g_snprintf (buffer, MAX_STRING_LENGTH, "\"%s\"", params[i + 1].data.d_string); g_snprintf (buffer, MAX_STRING_LENGTH, "\"%s\"", params[i + 1].data.d_string);
text = buffer; text = buffer;
break; break;
case SF_BRUSH:
g_snprintf (buffer, MAX_STRING_LENGTH, "\"%s\"", params[i + 1].data.d_string);
text = buffer;
break;
default: default:
break; break;
} }
@ -871,6 +920,11 @@ script_fu_free_script (SFScript *script)
case SF_PATTERN: case SF_PATTERN:
g_free (script->arg_defaults[i].sfa_pattern); g_free (script->arg_defaults[i].sfa_pattern);
g_free (script->arg_values[i].sfa_pattern); g_free (script->arg_values[i].sfa_pattern);
break;
case SF_BRUSH:
g_free (script->arg_defaults[i].sfa_brush.name);
g_free (script->arg_values[i].sfa_brush.name);
break;
default: default:
break; break;
} }
@ -1131,6 +1185,16 @@ script_fu_interface (SFScript *script)
script_fu_pattern_preview, script_fu_pattern_preview,
&script->arg_values[i].sfa_pattern); &script->arg_values[i].sfa_pattern);
break; break;
case SF_BRUSH:
script->args_widgets[i] =
gimp_brush_select_widget("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_preview,
&script->arg_values[i].sfa_brush);
break;
default: default:
break; break;
@ -1250,6 +1314,26 @@ script_fu_pattern_preview(gchar *name,
*pname = g_strdup(name); *pname = g_strdup(name);
} }
static void
script_fu_brush_preview(char * name, /* Name */
gdouble opacity, /* opacity */
gint spacing, /* spacing */
gint paint_mode, /* paint_mode */
gint width, /* width */
gint height, /* height */
gchar * mask_data, /* mask data */
gint closing, /* dialog closing */
gpointer udata/* user data */)
{
SFBrush *brush = (SFBrush *)udata;
g_free(brush->name);
brush->name = g_strdup(name);
brush->opacity = opacity;
brush->spacing = spacing;
brush->paint_mode = paint_mode;
}
static void static void
script_fu_font_preview (GtkWidget *preview, script_fu_font_preview (GtkWidget *preview,
@ -1320,6 +1404,9 @@ script_fu_cleanup_widgets (SFScript *script)
case SF_PATTERN: case SF_PATTERN:
gimp_pattern_select_widget_close_popup(script->args_widgets[i]); gimp_pattern_select_widget_close_popup(script->args_widgets[i]);
break; break;
case SF_BRUSH:
gimp_brush_select_widget_close_popup(script->args_widgets[i]);
break;
default: default:
break; break;
} }
@ -1386,6 +1473,10 @@ script_fu_ok_callback (GtkWidget *widget,
case SF_PATTERN: case SF_PATTERN:
length += strlen (script->arg_values[i].sfa_pattern) + 3; length += strlen (script->arg_values[i].sfa_pattern) + 3;
break; break;
case SF_BRUSH:
length += strlen (script->arg_values[i].sfa_brush.name) + 3;
length += 36; /* Maximum size of three ints for opacity, spacing,mode*/
break;
default: default:
break; break;
} }
@ -1452,6 +1543,15 @@ script_fu_ok_callback (GtkWidget *widget,
g_snprintf (buffer, MAX_STRING_LENGTH, "\"%s\"",script->arg_values[i].sfa_pattern); g_snprintf (buffer, MAX_STRING_LENGTH, "\"%s\"",script->arg_values[i].sfa_pattern);
text = buffer; text = buffer;
break; break;
case SF_BRUSH:
g_snprintf (buffer, MAX_STRING_LENGTH,
"'(\"%s\" %f %d %d)",
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);
text = buffer;
break;
default: default:
break; break;
} }
@ -1689,6 +1789,13 @@ script_fu_reset_callback (GtkWidget *widget,
case SF_PATTERN: case SF_PATTERN:
gimp_pattern_select_widget_set_popup(script->args_widgets[i],script->arg_defaults[i].sfa_pattern); gimp_pattern_select_widget_set_popup(script->args_widgets[i],script->arg_defaults[i].sfa_pattern);
break; break;
case SF_BRUSH:
gimp_brush_select_widget_set_popup(script->args_widgets[i],
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;
default: default:
break; break;
} }

View File

@ -68,6 +68,15 @@ typedef struct
gchar *fontname; gchar *fontname;
} SFFont; } SFFont;
typedef struct
{
gchar *name;
gdouble opacity;
gint spacing;
gint paint_mode;
} SFBrush;
typedef union typedef union
{ {
gint32 sfa_image; gint32 sfa_image;
@ -80,6 +89,7 @@ typedef union
SFAdjustment sfa_adjustment; SFAdjustment sfa_adjustment;
SFFont sfa_font; SFFont sfa_font;
gchar * sfa_pattern; gchar * sfa_pattern;
SFBrush sfa_brush;
} SFArgValue; } SFArgValue;
typedef struct typedef struct
@ -175,6 +185,15 @@ static void script_fu_pattern_preview (gchar *name,
gint closing, gint closing,
gpointer udata); gpointer udata);
static void script_fu_brush_preview (char *, /* Name */
gdouble, /* opacity */
gint, /* spacing */
gint, /* paint_mode */
gint, /* width */
gint, /* height */
gchar *, /* mask data */
gint, /* dialog closing */
gpointer /* user data */);
@ -339,6 +358,7 @@ script_fu_add_script (LISP a)
gdouble color[3]; gdouble color[3];
LISP color_list; LISP color_list;
LISP adj_list; LISP adj_list;
LISP brush_list;
gchar *menu_path = NULL; gchar *menu_path = NULL;
/* Check the length of a */ /* Check the length of a */
@ -572,8 +592,30 @@ script_fu_add_script (LISP a)
args[i + 1].description = script->arg_labels[i]; args[i + 1].description = script->arg_labels[i];
break; break;
case SF_BRUSH:
if (!TYPEP (car (a), tc_cons))
return my_err ("script-fu-register: brush defaults must be a list", NIL);
brush_list = car (a);
script->arg_defaults[i].sfa_brush.name = g_strdup (get_c_string (car (brush_list)));
brush_list = cdr (brush_list);
script->arg_defaults[i].sfa_brush.opacity = get_c_double (car (brush_list));
brush_list = cdr (brush_list);
script->arg_defaults[i].sfa_brush.spacing = get_c_long (car (brush_list));
brush_list = cdr (brush_list);
script->arg_defaults[i].sfa_brush.paint_mode = get_c_long (car (brush_list));
script->arg_values[i].sfa_brush = script->arg_defaults[i].sfa_brush;
/* Need this since we need a copy of the string
* in the values area. We could free it later but the
* default one must hang around.
*/
script->arg_values[i].sfa_brush.name = g_strdup(script->arg_defaults[i].sfa_brush.name);
args[i + 1].type = PARAM_STRING;
args[i + 1].name = "brush";
args[i + 1].description = script->arg_labels[i];
break; break;
default: default:
break; break;
} }
@ -725,6 +767,9 @@ script_fu_script_proc (char *name,
case SF_PATTERN: case SF_PATTERN:
length += strlen (params[i + 1].data.d_string) + 3; length += strlen (params[i + 1].data.d_string) + 3;
break; break;
case SF_BRUSH:
length += strlen (params[i + 1].data.d_string) + 3;
break;
default: default:
break; break;
} }
@ -775,6 +820,10 @@ script_fu_script_proc (char *name,
g_snprintf (buffer, MAX_STRING_LENGTH, "\"%s\"", params[i + 1].data.d_string); g_snprintf (buffer, MAX_STRING_LENGTH, "\"%s\"", params[i + 1].data.d_string);
text = buffer; text = buffer;
break; break;
case SF_BRUSH:
g_snprintf (buffer, MAX_STRING_LENGTH, "\"%s\"", params[i + 1].data.d_string);
text = buffer;
break;
default: default:
break; break;
} }
@ -871,6 +920,11 @@ script_fu_free_script (SFScript *script)
case SF_PATTERN: case SF_PATTERN:
g_free (script->arg_defaults[i].sfa_pattern); g_free (script->arg_defaults[i].sfa_pattern);
g_free (script->arg_values[i].sfa_pattern); g_free (script->arg_values[i].sfa_pattern);
break;
case SF_BRUSH:
g_free (script->arg_defaults[i].sfa_brush.name);
g_free (script->arg_values[i].sfa_brush.name);
break;
default: default:
break; break;
} }
@ -1131,6 +1185,16 @@ script_fu_interface (SFScript *script)
script_fu_pattern_preview, script_fu_pattern_preview,
&script->arg_values[i].sfa_pattern); &script->arg_values[i].sfa_pattern);
break; break;
case SF_BRUSH:
script->args_widgets[i] =
gimp_brush_select_widget("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_preview,
&script->arg_values[i].sfa_brush);
break;
default: default:
break; break;
@ -1250,6 +1314,26 @@ script_fu_pattern_preview(gchar *name,
*pname = g_strdup(name); *pname = g_strdup(name);
} }
static void
script_fu_brush_preview(char * name, /* Name */
gdouble opacity, /* opacity */
gint spacing, /* spacing */
gint paint_mode, /* paint_mode */
gint width, /* width */
gint height, /* height */
gchar * mask_data, /* mask data */
gint closing, /* dialog closing */
gpointer udata/* user data */)
{
SFBrush *brush = (SFBrush *)udata;
g_free(brush->name);
brush->name = g_strdup(name);
brush->opacity = opacity;
brush->spacing = spacing;
brush->paint_mode = paint_mode;
}
static void static void
script_fu_font_preview (GtkWidget *preview, script_fu_font_preview (GtkWidget *preview,
@ -1320,6 +1404,9 @@ script_fu_cleanup_widgets (SFScript *script)
case SF_PATTERN: case SF_PATTERN:
gimp_pattern_select_widget_close_popup(script->args_widgets[i]); gimp_pattern_select_widget_close_popup(script->args_widgets[i]);
break; break;
case SF_BRUSH:
gimp_brush_select_widget_close_popup(script->args_widgets[i]);
break;
default: default:
break; break;
} }
@ -1386,6 +1473,10 @@ script_fu_ok_callback (GtkWidget *widget,
case SF_PATTERN: case SF_PATTERN:
length += strlen (script->arg_values[i].sfa_pattern) + 3; length += strlen (script->arg_values[i].sfa_pattern) + 3;
break; break;
case SF_BRUSH:
length += strlen (script->arg_values[i].sfa_brush.name) + 3;
length += 36; /* Maximum size of three ints for opacity, spacing,mode*/
break;
default: default:
break; break;
} }
@ -1452,6 +1543,15 @@ script_fu_ok_callback (GtkWidget *widget,
g_snprintf (buffer, MAX_STRING_LENGTH, "\"%s\"",script->arg_values[i].sfa_pattern); g_snprintf (buffer, MAX_STRING_LENGTH, "\"%s\"",script->arg_values[i].sfa_pattern);
text = buffer; text = buffer;
break; break;
case SF_BRUSH:
g_snprintf (buffer, MAX_STRING_LENGTH,
"'(\"%s\" %f %d %d)",
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);
text = buffer;
break;
default: default:
break; break;
} }
@ -1689,6 +1789,13 @@ script_fu_reset_callback (GtkWidget *widget,
case SF_PATTERN: case SF_PATTERN:
gimp_pattern_select_widget_set_popup(script->args_widgets[i],script->arg_defaults[i].sfa_pattern); gimp_pattern_select_widget_set_popup(script->args_widgets[i],script->arg_defaults[i].sfa_pattern);
break; break;
case SF_BRUSH:
gimp_brush_select_widget_set_popup(script->args_widgets[i],
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;
default: default:
break; break;
} }

View File

@ -477,6 +477,7 @@ init_constants ()
setvar (cintern ("SF-ADJUSTMENT"), flocons (SF_ADJUSTMENT), NIL); setvar (cintern ("SF-ADJUSTMENT"), flocons (SF_ADJUSTMENT), NIL);
setvar (cintern ("SF-FONT"), flocons (SF_FONT), NIL); setvar (cintern ("SF-FONT"), flocons (SF_FONT), NIL);
setvar (cintern ("SF-PATTERN"), flocons (SF_PATTERN), NIL); setvar (cintern ("SF-PATTERN"), flocons (SF_PATTERN), NIL);
setvar (cintern ("SF-BRUSH"), flocons (SF_BRUSH), NIL);
/* for SF_ADJUSTMENT */ /* for SF_ADJUSTMENT */
setvar (cintern ("SF-SLIDER"), flocons (SF_SLIDER), NIL); setvar (cintern ("SF-SLIDER"), flocons (SF_SLIDER), NIL);

View File

@ -81,7 +81,7 @@
"Hrvoje Horvat" "Hrvoje Horvat"
"07 April, 1998" "07 April, 1998"
"" ""
SF-STRING "Text Pattern" "Parque #1" SF-PATTERN "Pattern" "Parque #1"
SF-STRING "Text String" "The Gimp" SF-STRING "Text String" "The Gimp"
SF-VALUE "Font Size (in pixels)" "100" SF-VALUE "Font Size (in pixels)" "100"
SF-STRING "Font" "Roostheavy" SF-STRING "Font" "Roostheavy"

View File

@ -30,7 +30,7 @@
; ;
(define (script-fu-test-sphere radius light shadow bg-color sphere-color text pattern font size) (define (script-fu-test-sphere radius light shadow bg-color sphere-color brush text pattern font size)
(let* ((width (* radius 3.75)) (let* ((width (* radius 3.75))
(height (* radius 2.5)) (height (* radius 2.5))
(img (car (gimp-image-new width height RGB))) (img (car (gimp-image-new width height RGB)))
@ -97,6 +97,7 @@
SF-TOGGLE "Shadow" TRUE SF-TOGGLE "Shadow" TRUE
SF-COLOR "Background Color" '(255 255 255) SF-COLOR "Background Color" '(255 255 255)
SF-COLOR "Sphere Color" '(255 0 0) SF-COLOR "Sphere Color" '(255 0 0)
SF-BRUSH "Brush" '("Circle (03)" 100.0 44 0)
SF-STRING "Text" "Script-Fu rocks!" SF-STRING "Text" "Script-Fu rocks!"
SF-PATTERN "Pattern" "Maple Leaves" SF-PATTERN "Pattern" "Maple Leaves"
SF-FONT "Font" "-freefont-agate-normal-r-normal-*-24-*-*-*-p-*-*-*" SF-FONT "Font" "-freefont-agate-normal-r-normal-*-24-*-*-*-p-*-*-*"

View File

@ -8,7 +8,7 @@
;;; Code: ;;; Code:
(define (script-fu-trochoid base-radius-f wheel-radius-f pen-pos hue-rate (define (script-fu-trochoid base-radius-f wheel-radius-f pen-pos hue-rate
erase-before-draw) erase-before-draw brush-details)
(if 'not-guile (define modulo fmod)) (if 'not-guile (define modulo fmod))
(define (floor x) (- x (fmod x 1))) (define (floor x) (- x (fmod x 1)))
(define *prime-table* (define *prime-table*
@ -251,7 +251,7 @@
(define (trochoid-rotate-gear total-distance img use-this-drawable center-x (define (trochoid-rotate-gear total-distance img use-this-drawable center-x
center-y base-radius wheel-radius pen-pos hue-rate center-y base-radius wheel-radius pen-pos hue-rate
layer-paint-mode stroke-overwrite) layer-paint-mode stroke-overwrite brush-details)
(let* ((rad-of-wheel 0) (let* ((rad-of-wheel 0)
(steps-for-circle 100.0) (steps-for-circle 100.0)
(wheel-spin (/ total-distance (abs wheel-radius))) (wheel-spin (/ total-distance (abs wheel-radius)))
@ -331,6 +331,7 @@
background-color background-color
stroke-overwrite brush-opacity paint-mode)))) stroke-overwrite brush-opacity paint-mode))))
;; start of script-fu-trochoid ;; start of script-fu-trochoid
(gimp-brushes-set-brush (car brush-details))
(let* ((base-radius (floor (abs base-radius-f))) ; to int (let* ((base-radius (floor (abs base-radius-f))) ; to int
(wheel-radius (floor wheel-radius-f)) ; to int (wheel-radius (floor wheel-radius-f)) ; to int
(total-step-num (if (or (= 0 base-radius) (= 0 wheel-radius)) (total-step-num (if (or (= 0 base-radius) (= 0 wheel-radius))
@ -374,7 +375,7 @@
(trochoid-rotate-gear total-step-num img the-layer (trochoid-rotate-gear total-step-num img the-layer
(/ drawable-size 2) (/ drawable-size 2) (/ drawable-size 2) (/ drawable-size 2)
base-radius wheel-radius pen-pos hue-rate base-radius wheel-radius pen-pos hue-rate
layer-paint-mode (= 0 erase-before-draw))) layer-paint-mode (= 0 erase-before-draw) brush-details))
(gimp-palette-set-foreground old-rgb) (gimp-palette-set-foreground old-rgb)
(gimp-brushes-set-paint-mode old-paint-mode) (gimp-brushes-set-paint-mode old-paint-mode)
(gimp-image-enable-undo img) (gimp-image-enable-undo img)
@ -392,6 +393,7 @@
SF-ADJUSTMENT "Pen rad./wheel rad. [0.0:1.0]" '(0.8 0 1 .01 .01 2 0) SF-ADJUSTMENT "Pen rad./wheel rad. [0.0:1.0]" '(0.8 0 1 .01 .01 2 0)
SF-ADJUSTMENT "Hue Rate" '(1.0 0 1 .01 .01 2 0) SF-ADJUSTMENT "Hue Rate" '(1.0 0 1 .01 .01 2 0)
SF-VALUE "Erase before draw? [0/1]" "0" SF-VALUE "Erase before draw? [0/1]" "0"
SF-BRUSH "Use brush" '("Circle (05)" 1.0 44 2)
) )
;;; trochoid.scm ends here ;;; trochoid.scm ends here