app/patterns.c app/pattern_select.c app/internal_procs.c app/patterns.h

Thu Oct  1 22:39:14 BST 1998 Andy Thomas <alt@picnic.demon.co.uk>

	* app/patterns.c app/pattern_select.c app/internal_procs.c
	* app/patterns.h app/pattern_select.h app/plug_in.c
	* libgimp/gimpmenu.h libgimp/gimpmenu.c libgimp/Makefile.am
	* plug-ins/gfig/gfig.c plug-ins/script-fu/scripts/test-sphere.scm
	* plug-ins/script-fu/script-fu.c plug-ins/script-fu/script-fu-enums.h
	* plug-ins/script-fu/script-fu-scripts.c

	* New libgimp/gimppatternmenu.c

	Pattern dialog can now be controlled via the PDB. New widget (not true
	widget) type added to libgimpui (gimp_pattern_select_widget()). Plugins
	should easily be able to control & select patterns. Script-fu
	updated to use new widget. See the test script for example.
This commit is contained in:
BST 1998 Andy Thomas 1998-10-01 22:09:01 +00:00 committed by Andy Thomas
parent c615f15e73
commit e99f37ab19
38 changed files with 1876 additions and 98 deletions

View File

@ -1,3 +1,20 @@
Thu Oct 1 22:39:14 BST 1998 Andy Thomas <alt@picnic.demon.co.uk>
* app/patterns.c app/pattern_select.c app/internal_procs.c
* app/patterns.h app/pattern_select.h app/plug_in.c
* libgimp/gimpmenu.h libgimp/gimpmenu.c libgimp/Makefile.am
* plug-ins/gfig/gfig.c plug-ins/script-fu/scripts/test-sphere.scm
* plug-ins/script-fu/script-fu.c plug-ins/script-fu/script-fu-enums.h
* plug-ins/script-fu/script-fu-scripts.c
* New libgimp/gimppatternmenu.c
Pattern dialog can now be controlled via the PDB. New widget (not true
widget) type added to libgimpui (gimp_pattern_select_widget()). Plugins
should easily be able to control & select patterns. Script-fu
updated to use new widget. See the test script for example.
Thu Oct 1 17:10:32 BST 1998 Adam D. Moss <adam@gimp.org>
* app/gdisplay.c app/gdisplay.h: Okay, that didn't

View File

@ -52,6 +52,7 @@
#include "gimprc.h"
#include "interface.h"
#include "menus.h"
#include "pattern_select.h" /* Needed for closing pattern dialogs */
#include "plug_in.h"
#include "tile.h" /* ick. */
@ -1059,6 +1060,7 @@ plug_in_close (PlugIn *plug_in,
/* Close any dialogs that this plugin might have opened */
brushes_check_dialogs();
patterns_check_dialogs();
open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
}

View File

@ -34,13 +34,17 @@
#define MAX_CELL_SIZE 45
/* PDB interface data */
static int success;
static GSList *active_dialogs = NULL; /* List of active dialogs */
/*
#define STD_PATTERN_COLUMNS 6
#define STD_PATTERN_ROWS 5
*/
#define MAX_WIN_WIDTH (MIN_CELL_SIZE * NUM_PATTERN_COLUMNS)
#define MAX_WIN_HEIGHT (MIN_CELL_SIZE * NUM_PATTERN_ROWS)
#define MAX_WIN_WIDTH(psp) (MIN_CELL_SIZE * (psp)->NUM_PATTERN_COLUMNS)
#define MAX_WIN_HEIGHT(psp) (MIN_CELL_SIZE * (psp)->NUM_PATTERN_ROWS)
#define MARGIN_WIDTH 1
#define MARGIN_HEIGHT 1
#define PATTERN_EVENT_MASK GDK_BUTTON1_MOTION_MASK | \
@ -76,11 +80,14 @@ gint NUM_PATTERN_COLUMNS = 6;
gint NUM_PATTERN_ROWS = 5;
gint STD_CELL_SIZE = MIN_CELL_SIZE;
extern PatternSelectP pattern_select_dialog;
PatternSelectP
pattern_select_new ()
pattern_select_new (gchar * title,
gchar * initial_pattern)
{
PatternSelectP psp;
GPatternP active;
GPatternP active = NULL;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *sbar;
@ -88,13 +95,37 @@ pattern_select_new ()
psp = g_malloc (sizeof (_PatternSelect));
psp->preview = NULL;
psp->old_col = psp->old_row = 0;
psp->callback_name = NULL;
psp->pattern_popup = NULL;
psp->NUM_PATTERN_COLUMNS = 6;
psp->NUM_PATTERN_ROWS = 5;
psp->STD_CELL_SIZE = MIN_CELL_SIZE;
/* The shell and main vbox */
psp->shell = gtk_dialog_new ();
gtk_window_set_wmclass (GTK_WINDOW (psp->shell), "patternselection", "Gimp");
gtk_window_set_title (GTK_WINDOW (psp->shell), "Pattern Selection");
session_set_window_geometry (psp->shell, &pattern_select_session_info, TRUE);
if(!title)
{
gtk_window_set_title (GTK_WINDOW (psp->shell), "Pattern Selection");
session_set_window_geometry (psp->shell, &pattern_select_session_info, TRUE);
}
else
{
gtk_window_set_title (GTK_WINDOW (psp->shell), title);
if(initial_pattern && strlen(initial_pattern))
{
active = pattern_list_get_pattern(pattern_list,initial_pattern);
}
}
/* update the active selection */
if(!active)
active = get_active_pattern ();
psp->pattern = active;
gtk_window_set_policy(GTK_WINDOW(psp->shell), FALSE, TRUE, FALSE);
vbox = gtk_vbox_new (FALSE, 1);
@ -130,7 +161,7 @@ pattern_select_new ()
gtk_box_pack_start (GTK_BOX (hbox), psp->frame, TRUE, TRUE, 0);
psp->sbar_data = GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, MAX_WIN_HEIGHT, 1, 1, MAX_WIN_HEIGHT));
psp->sbar_data = GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, MAX_WIN_HEIGHT(psp), 1, 1, MAX_WIN_HEIGHT(psp)));
gtk_signal_connect (GTK_OBJECT (psp->sbar_data), "value_changed",
(GtkSignalFunc) pattern_select_scroll_update,
psp);
@ -141,8 +172,8 @@ pattern_select_new ()
psp->cell_width = STD_CELL_SIZE;
psp->cell_height = STD_CELL_SIZE;
psp->width = MAX_WIN_WIDTH;
psp->height = MAX_WIN_HEIGHT;
psp->width = MAX_WIN_WIDTH(psp);
psp->height = MAX_WIN_HEIGHT(psp);
psp->preview = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (psp->preview), psp->width, psp->height);
@ -177,15 +208,56 @@ pattern_select_new ()
preview_calc_scrollbar (psp);
display_patterns (psp);
/* update the active selection */
active = get_active_pattern ();
if (active)
pattern_select_select (psp, active->index);
return psp;
}
void
pattern_change_callbacks(PatternSelectP psp, gint closing)
{
gchar * name;
ProcRecord *prec = NULL;
GPatternP pattern;
int nreturn_vals;
static int busy = 0;
/* Any procs registered to callback? */
Argument *return_vals;
if(!psp || !psp->callback_name || busy != 0)
return;
busy = 1;
name = psp->callback_name;
pattern = psp->pattern;
/* If its still registered run it */
prec = procedural_db_lookup(name);
if(prec && pattern)
{
return_vals = procedural_db_run_proc (name,
&nreturn_vals,
PDB_STRING,pattern->name,
PDB_INT32,pattern->mask->width,
PDB_INT32,pattern->mask->height,
PDB_INT32,pattern->mask->bytes,
PDB_INT32,pattern->mask->bytes*pattern->mask->height*pattern->mask->width,
PDB_INT8ARRAY,temp_buf_data (pattern->mask),
PDB_INT32,closing,
PDB_END);
if (!return_vals || return_vals[0].value.pdb_int != PDB_SUCCESS)
g_message ("failed to run pattern callback function");
procedural_db_destroy_args (return_vals, nreturn_vals);
}
busy = 0;
}
void
pattern_select_select (PatternSelectP psp,
int index)
@ -193,8 +265,8 @@ pattern_select_select (PatternSelectP psp,
int row, col;
update_active_pattern_field (psp);
row = index / NUM_PATTERN_COLUMNS;
col = index - row * NUM_PATTERN_COLUMNS;
row = index / psp->NUM_PATTERN_COLUMNS;
col = index - row * psp->NUM_PATTERN_COLUMNS;
pattern_select_show_selected (psp, row, col);
}
@ -204,9 +276,19 @@ pattern_select_free (PatternSelectP psp)
{
if (psp)
{
session_get_window_info (psp->shell, &pattern_select_session_info);
/* Only main one is saved */
if(psp == pattern_select_dialog)
session_get_window_info (psp->shell, &pattern_select_session_info);
if (psp->pattern_popup != NULL)
gtk_widget_destroy (psp->pattern_popup);
if(psp->callback_name)
g_free(psp->callback_name);
/* remove from active list */
active_dialogs = g_slist_remove(active_dialogs,psp);
g_free (psp);
}
}
@ -406,7 +488,7 @@ display_patterns (PatternSelectP psp)
display_pattern (psp, pattern, col, row);
/* increment the counts */
if (++col == NUM_PATTERN_COLUMNS)
if (++col == psp->NUM_PATTERN_COLUMNS)
{
row ++;
col = 0;
@ -421,8 +503,6 @@ pattern_select_show_selected (PatternSelectP psp,
int row,
int col)
{
static int old_row = 0;
static int old_col = 0;
GdkRectangle area;
unsigned char * buf;
int yend;
@ -432,11 +512,11 @@ pattern_select_show_selected (PatternSelectP psp,
buf = (unsigned char *) g_malloc (sizeof (char) * psp->cell_width * 3);
if (old_col != col || old_row != row)
if (psp->old_col != col || psp->old_row != row)
{
/* remove the old selection */
offset_x = old_col * psp->cell_width;
offset_y = old_row * psp->cell_height - psp->scroll_offset;
offset_x = psp->old_col * psp->cell_width;
offset_y = psp->old_row * psp->cell_height - psp->scroll_offset;
ystart = BOUNDS (offset_y , 0, psp->preview->requisition.height);
yend = BOUNDS (offset_y + psp->cell_height, 0, psp->preview->requisition.height);
@ -489,8 +569,8 @@ pattern_select_show_selected (PatternSelectP psp,
area.height = yend - ystart;
gtk_widget_draw (psp->preview, &area);
old_row = row;
old_col = col;
psp->old_row = row;
psp->old_col = col;
g_free (buf);
}
@ -510,7 +590,7 @@ preview_calc_scrollbar (PatternSelectP psp)
int max;
psp->scroll_offset = 0;
num_rows = (num_patterns + NUM_PATTERN_COLUMNS - 1) / NUM_PATTERN_COLUMNS;
num_rows = (num_patterns + psp->NUM_PATTERN_COLUMNS - 1) / psp->NUM_PATTERN_COLUMNS;
max = num_rows * psp->cell_width;
if (!num_rows) num_rows = 1;
page_size = psp->preview->allocation.height;
@ -530,7 +610,10 @@ update_active_pattern_field (PatternSelectP psp)
GPatternP pattern;
char buf[32];
pattern = get_active_pattern ();
if(pattern_select_dialog == psp)
pattern = get_active_pattern ();
else
pattern = psp->pattern;
if (!pattern)
return;
@ -554,19 +637,19 @@ pattern_select_resize (GtkWidget *widget,
wid = widget->allocation.width-4;
for(now = MIN_CELL_SIZE, STD_CELL_SIZE = MIN_CELL_SIZE;
for(now = MIN_CELL_SIZE, psp->STD_CELL_SIZE = MIN_CELL_SIZE;
now < MAX_CELL_SIZE; ++now)
{
if ((wid % now) < (wid % STD_CELL_SIZE)) STD_CELL_SIZE = now;
if ((wid % STD_CELL_SIZE) == 0)
if ((wid % now) < (wid % psp->STD_CELL_SIZE)) psp->STD_CELL_SIZE = now;
if ((wid % psp->STD_CELL_SIZE) == 0)
break;
}
NUM_PATTERN_COLUMNS = wid / STD_CELL_SIZE;
NUM_PATTERN_ROWS = (gint) (num_patterns + NUM_PATTERN_COLUMNS-1) / NUM_PATTERN_COLUMNS;
psp->NUM_PATTERN_COLUMNS = wid / psp->STD_CELL_SIZE;
psp->NUM_PATTERN_ROWS = (gint) (num_patterns + psp->NUM_PATTERN_COLUMNS-1) / psp->NUM_PATTERN_COLUMNS;
psp->cell_width = STD_CELL_SIZE;
psp->cell_height = STD_CELL_SIZE;
psp->cell_width = psp->STD_CELL_SIZE;
psp->cell_height = psp->STD_CELL_SIZE;
psp->width = widget->allocation.width - 4;
psp->height = widget->allocation.height - 4;
@ -612,7 +695,7 @@ pattern_select_events (GtkWidget *widget,
{
col = bevent->x / psp->cell_width;
row = (bevent->y + psp->scroll_offset) / psp->cell_height;
index = row * NUM_PATTERN_COLUMNS + col;
index = row * psp->NUM_PATTERN_COLUMNS + col;
/* Get the pattern and display the popup pattern preview */
if ((pattern = get_pattern_by_index (index)))
@ -623,8 +706,16 @@ pattern_select_events (GtkWidget *widget,
GDK_BUTTON_RELEASE_MASK),
NULL, NULL, bevent->time);
/* Make this pattern the active pattern */
select_pattern (pattern);
if(pattern_select_dialog == psp)
{
/* Make this pattern the active pattern */
select_pattern (pattern);
}
else
{
psp->pattern = pattern;
pattern_select_select (psp, pattern->index);
}
/* Show the pattern popup window if the pattern is too large */
if (pattern->mask->width > psp->cell_width ||
pattern->mask->height > psp->cell_height)
@ -643,6 +734,9 @@ pattern_select_events (GtkWidget *widget,
/* Close the brush popup window */
pattern_popup_close (psp);
/* Call any callbacks registered */
pattern_change_callbacks(psp,0);
}
break;
@ -668,9 +762,20 @@ pattern_select_close_callback (GtkWidget *w,
gpointer client_data)
{
PatternSelectP psp;
psp = (PatternSelectP) client_data;
if (GTK_WIDGET_VISIBLE (psp->shell))
gtk_widget_hide (psp->shell);
/* Free memory if poping down dialog which is not the main one */
if(psp != pattern_select_dialog)
{
/* Send data back */
pattern_change_callbacks(psp,1);
gtk_widget_destroy(psp->shell);
pattern_select_free(psp);
}
}
static void
@ -715,14 +820,298 @@ pattern_select_scroll_update (GtkAdjustment *adjustment,
psp->scroll_offset = adjustment->value;
display_patterns (psp);
active = get_active_pattern ();
if(pattern_select_dialog == psp)
active = get_active_pattern ();
else
active = psp->pattern;
if (active)
{
row = active->index / NUM_PATTERN_COLUMNS;
col = active->index - row * NUM_PATTERN_COLUMNS;
row = active->index / psp->NUM_PATTERN_COLUMNS;
col = active->index - row * psp->NUM_PATTERN_COLUMNS;
pattern_select_show_selected (psp, row, col);
}
draw_preview (psp);
}
}
/* Close active dialogs that no longer have PDB registered for them */
void
patterns_check_dialogs()
{
GSList *list;
PatternSelectP psp;
gchar * name;
ProcRecord *prec = NULL;
list = active_dialogs;
while (list)
{
psp = (PatternSelectP) list->data;
list = list->next;
name = psp->callback_name;
prec = procedural_db_lookup(name);
if(!prec)
{
active_dialogs = g_slist_remove(active_dialogs,psp);
/* Can alter active_dialogs list*/
pattern_select_close_callback(NULL,psp);
}
}
}
/************
* PDB interfaces.
*/
static Argument *
patterns_popup_invoker (Argument *args)
{
gchar * name;
gchar * title;
gchar * initial_pattern;
ProcRecord *prec = NULL;
PatternSelectP newdialog;
success = (name = (char *) args[0].value.pdb_pointer) != NULL;
title = (char *) args[1].value.pdb_pointer;
initial_pattern = (char *) args[2].value.pdb_pointer;
/* Check the proc exists */
if(!success || (prec = procedural_db_lookup(name)) == NULL)
{
success = 0;
return procedural_db_return_args (&patterns_popup_proc, success);
}
if(initial_pattern && strlen(initial_pattern))
newdialog = pattern_select_new(title,
initial_pattern);
else
newdialog = pattern_select_new(title,NULL);
/* Add to list of proc to run when pattern changes */
newdialog->callback_name = g_strdup(name);
/* Add to active pattern dialogs list */
active_dialogs = g_slist_append(active_dialogs,newdialog);
return procedural_db_return_args (&patterns_popup_proc, success);
}
/* The procedure definition */
ProcArg patterns_popup_in_args[] =
{
{ PDB_STRING,
"pattern_callback",
"the callback PDB proc to call when pattern selection is made"
},
{ PDB_STRING,
"popup title",
"title to give the pattern popup window",
},
{ PDB_STRING,
"initial pattern",
"The name of the pattern to set as the first selected",
},
};
ProcRecord patterns_popup_proc =
{
"gimp_patterns_popup",
"Invokes the Gimp pattern selection",
"This procedure popups the pattern selection dialog",
"Andy Thomas",
"Andy Thomas",
"1998",
PDB_INTERNAL,
/* Input arguments */
sizeof(patterns_popup_in_args) / sizeof(patterns_popup_in_args[0]),
patterns_popup_in_args,
/* Output arguments */
0,
NULL,
/* Exec method */
{ { patterns_popup_invoker } },
};
static PatternSelectP
patterns_get_patternselect(gchar *name)
{
GSList *list;
PatternSelectP psp;
list = active_dialogs;
while (list)
{
psp = (PatternSelectP) list->data;
list = list->next;
if(strcmp(name,psp->callback_name) == 0)
{
return psp;
}
}
return NULL;
}
static Argument *
patterns_close_popup_invoker (Argument *args)
{
gchar * name;
ProcRecord *prec = NULL;
PatternSelectP psp;
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 (&patterns_close_popup_proc, success);
}
psp = patterns_get_patternselect(name);
if(psp)
{
active_dialogs = g_slist_remove(active_dialogs,psp);
if (GTK_WIDGET_VISIBLE (psp->shell))
gtk_widget_hide (psp->shell);
/* Free memory if poping down dialog which is not the main one */
if(psp != pattern_select_dialog)
{
/* Send data back */
gtk_widget_destroy(psp->shell);
pattern_select_free(psp);
}
}
else
{
success = FALSE;
}
return procedural_db_return_args (&patterns_close_popup_proc, success);
}
/* The procedure definition */
ProcArg patterns_close_popup_in_args[] =
{
{ PDB_STRING,
"callback PDB entry name",
"The name of the callback registered for this popup",
},
};
ProcRecord patterns_close_popup_proc =
{
"gimp_patterns_close_popup",
"Popdown the Gimp pattern selection",
"This procedure closes an opened pattern selection dialog",
"Andy Thomas",
"Andy Thomas",
"1998",
PDB_INTERNAL,
/* Input arguments */
sizeof(patterns_close_popup_in_args) / sizeof(patterns_close_popup_in_args[0]),
patterns_close_popup_in_args,
/* Output arguments */
0,
NULL,
/* Exec method */
{ { patterns_close_popup_invoker } },
};
static Argument *
patterns_set_popup_invoker (Argument *args)
{
gchar * pdbname;
gchar * pattern_name;
ProcRecord *prec = NULL;
PatternSelectP psp;
success = (pdbname = (char *) args[0].value.pdb_pointer) != NULL;
pattern_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 (&patterns_set_popup_proc, success);
}
psp = patterns_get_patternselect(pdbname);
if(psp)
{
/* Can alter active_dialogs list*/
GPatternP active = pattern_list_get_pattern(pattern_list,pattern_name);
if(active)
{
psp->pattern = active;
pattern_select_select (psp, active->index);
success = TRUE;
}
}
else
{
success = FALSE;
}
return procedural_db_return_args (&patterns_close_popup_proc, success);
}
/* The procedure definition */
ProcArg patterns_set_popup_in_args[] =
{
{ PDB_STRING,
"callback PDB entry name",
"The name of the callback registered for this popup",
},
{ PDB_STRING,
"pattern name to set",
"The name of the pattern to set as selected",
},
};
ProcRecord patterns_set_popup_proc =
{
"gimp_patterns_set_popup",
"Sets the current pattern selection in a popup",
"Sets the current pattern selection in a popup",
"Andy Thomas",
"Andy Thomas",
"1998",
PDB_INTERNAL,
/* Input arguments */
sizeof(patterns_set_popup_in_args) / sizeof(patterns_set_popup_in_args[0]),
patterns_set_popup_in_args,
/* Output arguments */
0,
NULL,
/* Exec method */
{ { patterns_set_popup_invoker } },
};

View File

@ -18,6 +18,8 @@
#ifndef __PATTERN_SELECT_H__
#define __PATTERN_SELECT_H__
#include "patterns.h"
typedef struct _PatternSelect _PatternSelect, *PatternSelectP;
struct _PatternSelect {
@ -35,11 +37,27 @@ struct _PatternSelect {
/* Pattern popup */
GtkWidget *pattern_popup;
GtkWidget *pattern_preview;
/* Call back function name */
gchar * callback_name;
gint old_row;
gint old_col;
/* Current pattern */
GPatternP pattern;
/* To calc column pos. */
gint NUM_PATTERN_COLUMNS;
gint NUM_PATTERN_ROWS;
gint STD_CELL_SIZE;
};
PatternSelectP pattern_select_new (void);
PatternSelectP pattern_select_new (gchar *,gchar *);
void pattern_select_select (PatternSelectP, int);
void pattern_select_free (PatternSelectP);
void patterns_check_dialogs(void);
/* PDB entry */
extern ProcRecord patterns_popup_proc;
extern ProcRecord patterns_close_popup_proc;
extern ProcRecord patterns_set_popup_proc;
#endif /* __PATTERN_SELECT_H__ */

View File

@ -52,6 +52,7 @@
#include "gimprc.h"
#include "interface.h"
#include "menus.h"
#include "pattern_select.h" /* Needed for closing pattern dialogs */
#include "plug_in.h"
#include "tile.h" /* ick. */
@ -1059,6 +1060,7 @@ plug_in_close (PlugIn *plug_in,
/* Close any dialogs that this plugin might have opened */
brushes_check_dialogs();
patterns_check_dialogs();
open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
}

View File

@ -52,6 +52,7 @@
#include "gimprc.h"
#include "interface.h"
#include "menus.h"
#include "pattern_select.h" /* Needed for closing pattern dialogs */
#include "plug_in.h"
#include "tile.h" /* ick. */
@ -1059,6 +1060,7 @@ plug_in_close (PlugIn *plug_in,
/* Close any dialogs that this plugin might have opened */
brushes_check_dialogs();
patterns_check_dialogs();
open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
}

View File

@ -60,6 +60,7 @@
#include "paintbrush.h"
#include "palette.h"
#include "patterns.h"
#include "pattern_select.h"
#include "pencil.h"
#include "perspective_tool.h"
#include "posterize.h"
@ -78,7 +79,7 @@ internal_procs_init ()
{
gfloat pcount = 0;
/* grep -c procedural_db_register internal_procs.c */
gfloat total_pcount = 213;
gfloat total_pcount = 217;
app_init_update_status("Internal Procedures", "Tool procedures",
pcount/total_pcount);
@ -328,6 +329,10 @@ internal_procs_init ()
procedural_db_register (&patterns_get_pattern_proc); pcount++;
procedural_db_register (&patterns_set_pattern_proc); pcount++;
procedural_db_register (&patterns_list_proc); pcount++;
procedural_db_register (&patterns_get_pattern_data_proc); pcount++;
procedural_db_register (&patterns_popup_proc); pcount++;
procedural_db_register (&patterns_close_popup_proc); pcount++;
procedural_db_register (&patterns_set_popup_proc); pcount++;
procedural_db_register (&gradients_get_list_proc); pcount++;
procedural_db_register (&gradients_get_active_proc); pcount++;

View File

@ -52,6 +52,7 @@
#include "gimprc.h"
#include "interface.h"
#include "menus.h"
#include "pattern_select.h" /* Needed for closing pattern dialogs */
#include "plug_in.h"
#include "tile.h" /* ick. */
@ -1059,6 +1060,7 @@ plug_in_close (PlugIn *plug_in,
/* Close any dialogs that this plugin might have opened */
brushes_check_dialogs();
patterns_check_dialogs();
open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
}

View File

@ -34,13 +34,17 @@
#define MAX_CELL_SIZE 45
/* PDB interface data */
static int success;
static GSList *active_dialogs = NULL; /* List of active dialogs */
/*
#define STD_PATTERN_COLUMNS 6
#define STD_PATTERN_ROWS 5
*/
#define MAX_WIN_WIDTH (MIN_CELL_SIZE * NUM_PATTERN_COLUMNS)
#define MAX_WIN_HEIGHT (MIN_CELL_SIZE * NUM_PATTERN_ROWS)
#define MAX_WIN_WIDTH(psp) (MIN_CELL_SIZE * (psp)->NUM_PATTERN_COLUMNS)
#define MAX_WIN_HEIGHT(psp) (MIN_CELL_SIZE * (psp)->NUM_PATTERN_ROWS)
#define MARGIN_WIDTH 1
#define MARGIN_HEIGHT 1
#define PATTERN_EVENT_MASK GDK_BUTTON1_MOTION_MASK | \
@ -76,11 +80,14 @@ gint NUM_PATTERN_COLUMNS = 6;
gint NUM_PATTERN_ROWS = 5;
gint STD_CELL_SIZE = MIN_CELL_SIZE;
extern PatternSelectP pattern_select_dialog;
PatternSelectP
pattern_select_new ()
pattern_select_new (gchar * title,
gchar * initial_pattern)
{
PatternSelectP psp;
GPatternP active;
GPatternP active = NULL;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *sbar;
@ -88,13 +95,37 @@ pattern_select_new ()
psp = g_malloc (sizeof (_PatternSelect));
psp->preview = NULL;
psp->old_col = psp->old_row = 0;
psp->callback_name = NULL;
psp->pattern_popup = NULL;
psp->NUM_PATTERN_COLUMNS = 6;
psp->NUM_PATTERN_ROWS = 5;
psp->STD_CELL_SIZE = MIN_CELL_SIZE;
/* The shell and main vbox */
psp->shell = gtk_dialog_new ();
gtk_window_set_wmclass (GTK_WINDOW (psp->shell), "patternselection", "Gimp");
gtk_window_set_title (GTK_WINDOW (psp->shell), "Pattern Selection");
session_set_window_geometry (psp->shell, &pattern_select_session_info, TRUE);
if(!title)
{
gtk_window_set_title (GTK_WINDOW (psp->shell), "Pattern Selection");
session_set_window_geometry (psp->shell, &pattern_select_session_info, TRUE);
}
else
{
gtk_window_set_title (GTK_WINDOW (psp->shell), title);
if(initial_pattern && strlen(initial_pattern))
{
active = pattern_list_get_pattern(pattern_list,initial_pattern);
}
}
/* update the active selection */
if(!active)
active = get_active_pattern ();
psp->pattern = active;
gtk_window_set_policy(GTK_WINDOW(psp->shell), FALSE, TRUE, FALSE);
vbox = gtk_vbox_new (FALSE, 1);
@ -130,7 +161,7 @@ pattern_select_new ()
gtk_box_pack_start (GTK_BOX (hbox), psp->frame, TRUE, TRUE, 0);
psp->sbar_data = GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, MAX_WIN_HEIGHT, 1, 1, MAX_WIN_HEIGHT));
psp->sbar_data = GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, MAX_WIN_HEIGHT(psp), 1, 1, MAX_WIN_HEIGHT(psp)));
gtk_signal_connect (GTK_OBJECT (psp->sbar_data), "value_changed",
(GtkSignalFunc) pattern_select_scroll_update,
psp);
@ -141,8 +172,8 @@ pattern_select_new ()
psp->cell_width = STD_CELL_SIZE;
psp->cell_height = STD_CELL_SIZE;
psp->width = MAX_WIN_WIDTH;
psp->height = MAX_WIN_HEIGHT;
psp->width = MAX_WIN_WIDTH(psp);
psp->height = MAX_WIN_HEIGHT(psp);
psp->preview = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (psp->preview), psp->width, psp->height);
@ -177,15 +208,56 @@ pattern_select_new ()
preview_calc_scrollbar (psp);
display_patterns (psp);
/* update the active selection */
active = get_active_pattern ();
if (active)
pattern_select_select (psp, active->index);
return psp;
}
void
pattern_change_callbacks(PatternSelectP psp, gint closing)
{
gchar * name;
ProcRecord *prec = NULL;
GPatternP pattern;
int nreturn_vals;
static int busy = 0;
/* Any procs registered to callback? */
Argument *return_vals;
if(!psp || !psp->callback_name || busy != 0)
return;
busy = 1;
name = psp->callback_name;
pattern = psp->pattern;
/* If its still registered run it */
prec = procedural_db_lookup(name);
if(prec && pattern)
{
return_vals = procedural_db_run_proc (name,
&nreturn_vals,
PDB_STRING,pattern->name,
PDB_INT32,pattern->mask->width,
PDB_INT32,pattern->mask->height,
PDB_INT32,pattern->mask->bytes,
PDB_INT32,pattern->mask->bytes*pattern->mask->height*pattern->mask->width,
PDB_INT8ARRAY,temp_buf_data (pattern->mask),
PDB_INT32,closing,
PDB_END);
if (!return_vals || return_vals[0].value.pdb_int != PDB_SUCCESS)
g_message ("failed to run pattern callback function");
procedural_db_destroy_args (return_vals, nreturn_vals);
}
busy = 0;
}
void
pattern_select_select (PatternSelectP psp,
int index)
@ -193,8 +265,8 @@ pattern_select_select (PatternSelectP psp,
int row, col;
update_active_pattern_field (psp);
row = index / NUM_PATTERN_COLUMNS;
col = index - row * NUM_PATTERN_COLUMNS;
row = index / psp->NUM_PATTERN_COLUMNS;
col = index - row * psp->NUM_PATTERN_COLUMNS;
pattern_select_show_selected (psp, row, col);
}
@ -204,9 +276,19 @@ pattern_select_free (PatternSelectP psp)
{
if (psp)
{
session_get_window_info (psp->shell, &pattern_select_session_info);
/* Only main one is saved */
if(psp == pattern_select_dialog)
session_get_window_info (psp->shell, &pattern_select_session_info);
if (psp->pattern_popup != NULL)
gtk_widget_destroy (psp->pattern_popup);
if(psp->callback_name)
g_free(psp->callback_name);
/* remove from active list */
active_dialogs = g_slist_remove(active_dialogs,psp);
g_free (psp);
}
}
@ -406,7 +488,7 @@ display_patterns (PatternSelectP psp)
display_pattern (psp, pattern, col, row);
/* increment the counts */
if (++col == NUM_PATTERN_COLUMNS)
if (++col == psp->NUM_PATTERN_COLUMNS)
{
row ++;
col = 0;
@ -421,8 +503,6 @@ pattern_select_show_selected (PatternSelectP psp,
int row,
int col)
{
static int old_row = 0;
static int old_col = 0;
GdkRectangle area;
unsigned char * buf;
int yend;
@ -432,11 +512,11 @@ pattern_select_show_selected (PatternSelectP psp,
buf = (unsigned char *) g_malloc (sizeof (char) * psp->cell_width * 3);
if (old_col != col || old_row != row)
if (psp->old_col != col || psp->old_row != row)
{
/* remove the old selection */
offset_x = old_col * psp->cell_width;
offset_y = old_row * psp->cell_height - psp->scroll_offset;
offset_x = psp->old_col * psp->cell_width;
offset_y = psp->old_row * psp->cell_height - psp->scroll_offset;
ystart = BOUNDS (offset_y , 0, psp->preview->requisition.height);
yend = BOUNDS (offset_y + psp->cell_height, 0, psp->preview->requisition.height);
@ -489,8 +569,8 @@ pattern_select_show_selected (PatternSelectP psp,
area.height = yend - ystart;
gtk_widget_draw (psp->preview, &area);
old_row = row;
old_col = col;
psp->old_row = row;
psp->old_col = col;
g_free (buf);
}
@ -510,7 +590,7 @@ preview_calc_scrollbar (PatternSelectP psp)
int max;
psp->scroll_offset = 0;
num_rows = (num_patterns + NUM_PATTERN_COLUMNS - 1) / NUM_PATTERN_COLUMNS;
num_rows = (num_patterns + psp->NUM_PATTERN_COLUMNS - 1) / psp->NUM_PATTERN_COLUMNS;
max = num_rows * psp->cell_width;
if (!num_rows) num_rows = 1;
page_size = psp->preview->allocation.height;
@ -530,7 +610,10 @@ update_active_pattern_field (PatternSelectP psp)
GPatternP pattern;
char buf[32];
pattern = get_active_pattern ();
if(pattern_select_dialog == psp)
pattern = get_active_pattern ();
else
pattern = psp->pattern;
if (!pattern)
return;
@ -554,19 +637,19 @@ pattern_select_resize (GtkWidget *widget,
wid = widget->allocation.width-4;
for(now = MIN_CELL_SIZE, STD_CELL_SIZE = MIN_CELL_SIZE;
for(now = MIN_CELL_SIZE, psp->STD_CELL_SIZE = MIN_CELL_SIZE;
now < MAX_CELL_SIZE; ++now)
{
if ((wid % now) < (wid % STD_CELL_SIZE)) STD_CELL_SIZE = now;
if ((wid % STD_CELL_SIZE) == 0)
if ((wid % now) < (wid % psp->STD_CELL_SIZE)) psp->STD_CELL_SIZE = now;
if ((wid % psp->STD_CELL_SIZE) == 0)
break;
}
NUM_PATTERN_COLUMNS = wid / STD_CELL_SIZE;
NUM_PATTERN_ROWS = (gint) (num_patterns + NUM_PATTERN_COLUMNS-1) / NUM_PATTERN_COLUMNS;
psp->NUM_PATTERN_COLUMNS = wid / psp->STD_CELL_SIZE;
psp->NUM_PATTERN_ROWS = (gint) (num_patterns + psp->NUM_PATTERN_COLUMNS-1) / psp->NUM_PATTERN_COLUMNS;
psp->cell_width = STD_CELL_SIZE;
psp->cell_height = STD_CELL_SIZE;
psp->cell_width = psp->STD_CELL_SIZE;
psp->cell_height = psp->STD_CELL_SIZE;
psp->width = widget->allocation.width - 4;
psp->height = widget->allocation.height - 4;
@ -612,7 +695,7 @@ pattern_select_events (GtkWidget *widget,
{
col = bevent->x / psp->cell_width;
row = (bevent->y + psp->scroll_offset) / psp->cell_height;
index = row * NUM_PATTERN_COLUMNS + col;
index = row * psp->NUM_PATTERN_COLUMNS + col;
/* Get the pattern and display the popup pattern preview */
if ((pattern = get_pattern_by_index (index)))
@ -623,8 +706,16 @@ pattern_select_events (GtkWidget *widget,
GDK_BUTTON_RELEASE_MASK),
NULL, NULL, bevent->time);
/* Make this pattern the active pattern */
select_pattern (pattern);
if(pattern_select_dialog == psp)
{
/* Make this pattern the active pattern */
select_pattern (pattern);
}
else
{
psp->pattern = pattern;
pattern_select_select (psp, pattern->index);
}
/* Show the pattern popup window if the pattern is too large */
if (pattern->mask->width > psp->cell_width ||
pattern->mask->height > psp->cell_height)
@ -643,6 +734,9 @@ pattern_select_events (GtkWidget *widget,
/* Close the brush popup window */
pattern_popup_close (psp);
/* Call any callbacks registered */
pattern_change_callbacks(psp,0);
}
break;
@ -668,9 +762,20 @@ pattern_select_close_callback (GtkWidget *w,
gpointer client_data)
{
PatternSelectP psp;
psp = (PatternSelectP) client_data;
if (GTK_WIDGET_VISIBLE (psp->shell))
gtk_widget_hide (psp->shell);
/* Free memory if poping down dialog which is not the main one */
if(psp != pattern_select_dialog)
{
/* Send data back */
pattern_change_callbacks(psp,1);
gtk_widget_destroy(psp->shell);
pattern_select_free(psp);
}
}
static void
@ -715,14 +820,298 @@ pattern_select_scroll_update (GtkAdjustment *adjustment,
psp->scroll_offset = adjustment->value;
display_patterns (psp);
active = get_active_pattern ();
if(pattern_select_dialog == psp)
active = get_active_pattern ();
else
active = psp->pattern;
if (active)
{
row = active->index / NUM_PATTERN_COLUMNS;
col = active->index - row * NUM_PATTERN_COLUMNS;
row = active->index / psp->NUM_PATTERN_COLUMNS;
col = active->index - row * psp->NUM_PATTERN_COLUMNS;
pattern_select_show_selected (psp, row, col);
}
draw_preview (psp);
}
}
/* Close active dialogs that no longer have PDB registered for them */
void
patterns_check_dialogs()
{
GSList *list;
PatternSelectP psp;
gchar * name;
ProcRecord *prec = NULL;
list = active_dialogs;
while (list)
{
psp = (PatternSelectP) list->data;
list = list->next;
name = psp->callback_name;
prec = procedural_db_lookup(name);
if(!prec)
{
active_dialogs = g_slist_remove(active_dialogs,psp);
/* Can alter active_dialogs list*/
pattern_select_close_callback(NULL,psp);
}
}
}
/************
* PDB interfaces.
*/
static Argument *
patterns_popup_invoker (Argument *args)
{
gchar * name;
gchar * title;
gchar * initial_pattern;
ProcRecord *prec = NULL;
PatternSelectP newdialog;
success = (name = (char *) args[0].value.pdb_pointer) != NULL;
title = (char *) args[1].value.pdb_pointer;
initial_pattern = (char *) args[2].value.pdb_pointer;
/* Check the proc exists */
if(!success || (prec = procedural_db_lookup(name)) == NULL)
{
success = 0;
return procedural_db_return_args (&patterns_popup_proc, success);
}
if(initial_pattern && strlen(initial_pattern))
newdialog = pattern_select_new(title,
initial_pattern);
else
newdialog = pattern_select_new(title,NULL);
/* Add to list of proc to run when pattern changes */
newdialog->callback_name = g_strdup(name);
/* Add to active pattern dialogs list */
active_dialogs = g_slist_append(active_dialogs,newdialog);
return procedural_db_return_args (&patterns_popup_proc, success);
}
/* The procedure definition */
ProcArg patterns_popup_in_args[] =
{
{ PDB_STRING,
"pattern_callback",
"the callback PDB proc to call when pattern selection is made"
},
{ PDB_STRING,
"popup title",
"title to give the pattern popup window",
},
{ PDB_STRING,
"initial pattern",
"The name of the pattern to set as the first selected",
},
};
ProcRecord patterns_popup_proc =
{
"gimp_patterns_popup",
"Invokes the Gimp pattern selection",
"This procedure popups the pattern selection dialog",
"Andy Thomas",
"Andy Thomas",
"1998",
PDB_INTERNAL,
/* Input arguments */
sizeof(patterns_popup_in_args) / sizeof(patterns_popup_in_args[0]),
patterns_popup_in_args,
/* Output arguments */
0,
NULL,
/* Exec method */
{ { patterns_popup_invoker } },
};
static PatternSelectP
patterns_get_patternselect(gchar *name)
{
GSList *list;
PatternSelectP psp;
list = active_dialogs;
while (list)
{
psp = (PatternSelectP) list->data;
list = list->next;
if(strcmp(name,psp->callback_name) == 0)
{
return psp;
}
}
return NULL;
}
static Argument *
patterns_close_popup_invoker (Argument *args)
{
gchar * name;
ProcRecord *prec = NULL;
PatternSelectP psp;
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 (&patterns_close_popup_proc, success);
}
psp = patterns_get_patternselect(name);
if(psp)
{
active_dialogs = g_slist_remove(active_dialogs,psp);
if (GTK_WIDGET_VISIBLE (psp->shell))
gtk_widget_hide (psp->shell);
/* Free memory if poping down dialog which is not the main one */
if(psp != pattern_select_dialog)
{
/* Send data back */
gtk_widget_destroy(psp->shell);
pattern_select_free(psp);
}
}
else
{
success = FALSE;
}
return procedural_db_return_args (&patterns_close_popup_proc, success);
}
/* The procedure definition */
ProcArg patterns_close_popup_in_args[] =
{
{ PDB_STRING,
"callback PDB entry name",
"The name of the callback registered for this popup",
},
};
ProcRecord patterns_close_popup_proc =
{
"gimp_patterns_close_popup",
"Popdown the Gimp pattern selection",
"This procedure closes an opened pattern selection dialog",
"Andy Thomas",
"Andy Thomas",
"1998",
PDB_INTERNAL,
/* Input arguments */
sizeof(patterns_close_popup_in_args) / sizeof(patterns_close_popup_in_args[0]),
patterns_close_popup_in_args,
/* Output arguments */
0,
NULL,
/* Exec method */
{ { patterns_close_popup_invoker } },
};
static Argument *
patterns_set_popup_invoker (Argument *args)
{
gchar * pdbname;
gchar * pattern_name;
ProcRecord *prec = NULL;
PatternSelectP psp;
success = (pdbname = (char *) args[0].value.pdb_pointer) != NULL;
pattern_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 (&patterns_set_popup_proc, success);
}
psp = patterns_get_patternselect(pdbname);
if(psp)
{
/* Can alter active_dialogs list*/
GPatternP active = pattern_list_get_pattern(pattern_list,pattern_name);
if(active)
{
psp->pattern = active;
pattern_select_select (psp, active->index);
success = TRUE;
}
}
else
{
success = FALSE;
}
return procedural_db_return_args (&patterns_close_popup_proc, success);
}
/* The procedure definition */
ProcArg patterns_set_popup_in_args[] =
{
{ PDB_STRING,
"callback PDB entry name",
"The name of the callback registered for this popup",
},
{ PDB_STRING,
"pattern name to set",
"The name of the pattern to set as selected",
},
};
ProcRecord patterns_set_popup_proc =
{
"gimp_patterns_set_popup",
"Sets the current pattern selection in a popup",
"Sets the current pattern selection in a popup",
"Andy Thomas",
"Andy Thomas",
"1998",
PDB_INTERNAL,
/* Input arguments */
sizeof(patterns_set_popup_in_args) / sizeof(patterns_set_popup_in_args[0]),
patterns_set_popup_in_args,
/* Output arguments */
0,
NULL,
/* Exec method */
{ { patterns_set_popup_invoker } },
};

View File

@ -18,6 +18,8 @@
#ifndef __PATTERN_SELECT_H__
#define __PATTERN_SELECT_H__
#include "patterns.h"
typedef struct _PatternSelect _PatternSelect, *PatternSelectP;
struct _PatternSelect {
@ -35,11 +37,27 @@ struct _PatternSelect {
/* Pattern popup */
GtkWidget *pattern_popup;
GtkWidget *pattern_preview;
/* Call back function name */
gchar * callback_name;
gint old_row;
gint old_col;
/* Current pattern */
GPatternP pattern;
/* To calc column pos. */
gint NUM_PATTERN_COLUMNS;
gint NUM_PATTERN_ROWS;
gint STD_CELL_SIZE;
};
PatternSelectP pattern_select_new (void);
PatternSelectP pattern_select_new (gchar *,gchar *);
void pattern_select_select (PatternSelectP, int);
void pattern_select_free (PatternSelectP);
void patterns_check_dialogs(void);
/* PDB entry */
extern ProcRecord patterns_popup_proc;
extern ProcRecord patterns_close_popup_proc;
extern ProcRecord patterns_set_popup_proc;
#endif /* __PATTERN_SELECT_H__ */

View File

@ -305,7 +305,7 @@ create_pattern_dialog ()
if (!pattern_select_dialog)
{
/* Create the dialog... */
pattern_select_dialog = pattern_select_new ();
pattern_select_dialog = pattern_select_new (NULL,NULL);
}
else
{
@ -395,6 +395,118 @@ ProcRecord patterns_get_pattern_proc =
};
/*******************************/
/* PATTERNS_GET_PATTERN_DATA */
static Argument *
patterns_get_pattern_data_invoker (Argument *args)
{
GPatternP patternp = NULL;
GSList *list;
char *name;
success = (name = (char *) args[0].value.pdb_pointer) != NULL;
if (!success)
{
/* No name use active pattern */
success = (patternp = get_active_pattern ()) != NULL;
}
else
{
list = pattern_list;
success = FALSE;
while (list)
{
patternp = (GPatternP) list->data;
if (!strcmp (patternp->name, name))
{
success = TRUE;
break;
}
list = g_slist_next (list);
}
}
return_args = procedural_db_return_args (&patterns_get_pattern_data_proc, success);
if (success)
{
return_args[1].value.pdb_pointer = g_strdup (patternp->name);
return_args[2].value.pdb_int = patternp->mask->width;
return_args[3].value.pdb_int = patternp->mask->height;
return_args[4].value.pdb_int = patternp->mask->bytes;
return_args[5].value.pdb_int = patternp->mask->height*patternp->mask->width*patternp->mask->bytes;
return_args[6].value.pdb_pointer = g_malloc(return_args[5].value.pdb_int);
g_memmove(return_args[6].value.pdb_pointer,
temp_buf_data (patternp->mask),
return_args[5].value.pdb_int);
}
return return_args;
}
/* The procedure definition */
ProcArg patterns_get_pattern_data_in_args[] =
{
{ PDB_STRING,
"name",
"the pattern name (\"\" means current active pattern) "
}
};
ProcArg patterns_get_pattern_data_out_args[] =
{
{ PDB_STRING,
"name",
"the pattern name"
},
{ PDB_INT32,
"width",
"the pattern width"
},
{ PDB_INT32,
"height",
"the pattern height"
},
{ PDB_INT32,
"mask bpp",
"pattern bytes per pixel"},
{ PDB_INT32,
"mask len",
"length of pattern mask data"},
{ PDB_INT8ARRAY,
"mask data",
"the pattern mask data"},
};
ProcRecord patterns_get_pattern_data_proc =
{
"gimp_patterns_get_pattern_data",
"Retrieve information about the currently active pattern (including data)",
"This procedure retrieves information about the currently active pattern. This includes the pattern name, and the pattern extents (width and height). It also returns the pattern data",
"Andy Thomas",
"Andy Thomas",
"1998",
PDB_INTERNAL,
/* Input arguments */
sizeof(patterns_get_pattern_data_in_args) / sizeof(patterns_get_pattern_data_in_args[0]),
patterns_get_pattern_data_in_args,
/* Output arguments */
sizeof(patterns_get_pattern_data_out_args) / sizeof(patterns_get_pattern_data_out_args[0]),
patterns_get_pattern_data_out_args,
/* Exec method */
{ { patterns_get_pattern_data_invoker } },
};
/**************************/
/* PATTERNS_SET_PATTERN */

View File

@ -50,5 +50,5 @@ extern int num_patterns;
extern ProcRecord patterns_get_pattern_proc;
extern ProcRecord patterns_set_pattern_proc;
extern ProcRecord patterns_list_proc;
extern ProcRecord patterns_get_pattern_data_proc;
#endif /* __PATTERNS_H__ */

View File

@ -52,6 +52,7 @@
#include "gimprc.h"
#include "interface.h"
#include "menus.h"
#include "pattern_select.h" /* Needed for closing pattern dialogs */
#include "plug_in.h"
#include "tile.h" /* ick. */
@ -1059,6 +1060,7 @@ plug_in_close (PlugIn *plug_in,
/* Close any dialogs that this plugin might have opened */
brushes_check_dialogs();
patterns_check_dialogs();
open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
}

View File

@ -52,6 +52,7 @@
#include "gimprc.h"
#include "interface.h"
#include "menus.h"
#include "pattern_select.h" /* Needed for closing pattern dialogs */
#include "plug_in.h"
#include "tile.h" /* ick. */
@ -1059,6 +1060,7 @@ plug_in_close (PlugIn *plug_in,
/* Close any dialogs that this plugin might have opened */
brushes_check_dialogs();
patterns_check_dialogs();
open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
}

View File

@ -52,6 +52,7 @@
#include "gimprc.h"
#include "interface.h"
#include "menus.h"
#include "pattern_select.h" /* Needed for closing pattern dialogs */
#include "plug_in.h"
#include "tile.h" /* ick. */
@ -1059,6 +1060,7 @@ plug_in_close (PlugIn *plug_in,
/* Close any dialogs that this plugin might have opened */
brushes_check_dialogs();
patterns_check_dialogs();
open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
}

View File

@ -52,6 +52,7 @@
#include "gimprc.h"
#include "interface.h"
#include "menus.h"
#include "pattern_select.h" /* Needed for closing pattern dialogs */
#include "plug_in.h"
#include "tile.h" /* ick. */
@ -1059,6 +1060,7 @@ plug_in_close (PlugIn *plug_in,
/* Close any dialogs that this plugin might have opened */
brushes_check_dialogs();
patterns_check_dialogs();
open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
}

View File

@ -52,6 +52,7 @@
#include "gimprc.h"
#include "interface.h"
#include "menus.h"
#include "pattern_select.h" /* Needed for closing pattern dialogs */
#include "plug_in.h"
#include "tile.h" /* ick. */
@ -1059,6 +1060,7 @@ plug_in_close (PlugIn *plug_in,
/* Close any dialogs that this plugin might have opened */
brushes_check_dialogs();
patterns_check_dialogs();
open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
}

View File

@ -52,6 +52,7 @@
#include "gimprc.h"
#include "interface.h"
#include "menus.h"
#include "pattern_select.h" /* Needed for closing pattern dialogs */
#include "plug_in.h"
#include "tile.h" /* ick. */
@ -1059,6 +1060,7 @@ plug_in_close (PlugIn *plug_in,
/* Close any dialogs that this plugin might have opened */
brushes_check_dialogs();
patterns_check_dialogs();
open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
}

View File

@ -52,6 +52,7 @@
#include "gimprc.h"
#include "interface.h"
#include "menus.h"
#include "pattern_select.h" /* Needed for closing pattern dialogs */
#include "plug_in.h"
#include "tile.h" /* ick. */
@ -1059,6 +1060,7 @@ plug_in_close (PlugIn *plug_in,
/* Close any dialogs that this plugin might have opened */
brushes_check_dialogs();
patterns_check_dialogs();
open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
}

View File

@ -52,6 +52,7 @@
#include "gimprc.h"
#include "interface.h"
#include "menus.h"
#include "pattern_select.h" /* Needed for closing pattern dialogs */
#include "plug_in.h"
#include "tile.h" /* ick. */
@ -1059,6 +1060,7 @@ plug_in_close (PlugIn *plug_in,
/* Close any dialogs that this plugin might have opened */
brushes_check_dialogs();
patterns_check_dialogs();
open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
}

View File

@ -52,6 +52,7 @@
#include "gimprc.h"
#include "interface.h"
#include "menus.h"
#include "pattern_select.h" /* Needed for closing pattern dialogs */
#include "plug_in.h"
#include "tile.h" /* ick. */
@ -1059,6 +1060,7 @@ plug_in_close (PlugIn *plug_in,
/* Close any dialogs that this plugin might have opened */
brushes_check_dialogs();
patterns_check_dialogs();
open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
}

View File

@ -52,6 +52,7 @@
#include "gimprc.h"
#include "interface.h"
#include "menus.h"
#include "pattern_select.h" /* Needed for closing pattern dialogs */
#include "plug_in.h"
#include "tile.h" /* ick. */
@ -1059,6 +1060,7 @@ plug_in_close (PlugIn *plug_in,
/* Close any dialogs that this plugin might have opened */
brushes_check_dialogs();
patterns_check_dialogs();
open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
}

View File

@ -52,6 +52,7 @@
#include "gimprc.h"
#include "interface.h"
#include "menus.h"
#include "pattern_select.h" /* Needed for closing pattern dialogs */
#include "plug_in.h"
#include "tile.h" /* ick. */
@ -1059,6 +1060,7 @@ plug_in_close (PlugIn *plug_in,
/* Close any dialogs that this plugin might have opened */
brushes_check_dialogs();
patterns_check_dialogs();
open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
}

View File

@ -52,6 +52,7 @@
#include "gimprc.h"
#include "interface.h"
#include "menus.h"
#include "pattern_select.h" /* Needed for closing pattern dialogs */
#include "plug_in.h"
#include "tile.h" /* ick. */
@ -1059,6 +1060,7 @@ plug_in_close (PlugIn *plug_in,
/* Close any dialogs that this plugin might have opened */
brushes_check_dialogs();
patterns_check_dialogs();
open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
}

View File

@ -52,6 +52,7 @@
#include "gimprc.h"
#include "interface.h"
#include "menus.h"
#include "pattern_select.h" /* Needed for closing pattern dialogs */
#include "plug_in.h"
#include "tile.h" /* ick. */
@ -1059,6 +1060,7 @@ plug_in_close (PlugIn *plug_in,
/* Close any dialogs that this plugin might have opened */
brushes_check_dialogs();
patterns_check_dialogs();
open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
}

View File

@ -52,6 +52,7 @@
#include "gimprc.h"
#include "interface.h"
#include "menus.h"
#include "pattern_select.h" /* Needed for closing pattern dialogs */
#include "plug_in.h"
#include "tile.h" /* ick. */
@ -1059,6 +1060,7 @@ plug_in_close (PlugIn *plug_in,
/* Close any dialogs that this plugin might have opened */
brushes_check_dialogs();
patterns_check_dialogs();
open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
}

View File

@ -52,6 +52,7 @@
#include "gimprc.h"
#include "interface.h"
#include "menus.h"
#include "pattern_select.h" /* Needed for closing pattern dialogs */
#include "plug_in.h"
#include "tile.h" /* ick. */
@ -1059,6 +1060,7 @@ plug_in_close (PlugIn *plug_in,
/* Close any dialogs that this plugin might have opened */
brushes_check_dialogs();
patterns_check_dialogs();
open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
}

View File

@ -52,6 +52,7 @@
#include "gimprc.h"
#include "interface.h"
#include "menus.h"
#include "pattern_select.h" /* Needed for closing pattern dialogs */
#include "plug_in.h"
#include "tile.h" /* ick. */
@ -1059,6 +1060,7 @@ plug_in_close (PlugIn *plug_in,
/* Close any dialogs that this plugin might have opened */
brushes_check_dialogs();
patterns_check_dialogs();
open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
}

View File

@ -35,7 +35,8 @@ libgimp_la_SOURCES = \
gimpwire.h
libgimpui_la_SOURCES = \
gimpmenu.c
gimpmenu.c \
gimppatternmenu.c
gimpinclude_HEADERS = \
gimp.h \

View File

@ -35,15 +35,31 @@ struct _GBrushData {
gchar *brush_mask_data;
GRunBrushCallback callback;
gint closing;
gpointer udata;
};
typedef struct _GBrushData GBrushData;
/* Copy data from temp_PDB call */
struct _GPatternData {
gint busy;
gchar *pname;
gint width;
gint height;
gint bytes;
gchar *pattern_mask_data;
GRunPatternCallback callback;
gint closing;
gpointer udata;
};
typedef struct _GPatternData GPatternData;
static void gimp_menu_callback (GtkWidget *w,
gint32 *id);
static void do_brush_callback (GBrushData *bdata);
static gint idle_test (GBrushData *bdata);
static gint idle_test_brush (GBrushData *bdata);
static gint idle_test_pattern (GPatternData *pdata);
static void temp_brush_invoker (char *name,
int nparams,
GParam *param,
@ -59,7 +75,9 @@ static gchar* gen_temp_plugin_name (void);
void gimp_run_temp (void);
static GHashTable *gbrush_ht = NULL;
static GHashTable *gpattern_ht = NULL;
static GBrushData *active_brush_pdb = NULL;
static GPatternData *active_pattern_pdb = NULL;
GtkWidget*
@ -431,7 +449,8 @@ do_brush_callback(GBrushData * bdata)
bdata->width,
bdata->height,
bdata->brush_mask_data,
bdata->closing);
bdata->closing,
bdata->udata);
if(bdata->bname)
g_free(bdata->bname);
@ -443,14 +462,46 @@ do_brush_callback(GBrushData * bdata)
bdata->bname = bdata->brush_mask_data = 0;
}
static void
do_pattern_callback(GPatternData * pdata)
{
if(!pdata->busy)
return;
if(pdata->callback)
pdata->callback(pdata->pname,
pdata->width,
pdata->height,
pdata->bytes,
pdata->pattern_mask_data,
pdata->closing,
pdata->udata);
if(pdata->pname)
g_free(pdata->pname);
if(pdata->pattern_mask_data)
g_free(pdata->pattern_mask_data);
pdata->busy = 0;
pdata->pname = pdata->pattern_mask_data = 0;
}
static gint
idle_test (GBrushData * bdata)
idle_test_brush (GBrushData * bdata)
{
do_brush_callback(bdata);
return FALSE;
}
static gint
idle_test_pattern (GPatternData * pdata)
{
do_pattern_callback(pdata);
return FALSE;
}
static void
temp_brush_invoker(char *name,
int nparams,
@ -493,7 +544,47 @@ temp_brush_invoker(char *name,
active_brush_pdb = bdata;
bdata->busy = 1;
gtk_idle_add((GtkFunction) idle_test,active_brush_pdb);
gtk_idle_add((GtkFunction) idle_test_brush,active_brush_pdb);
}
}
*nreturn_vals = 1;
*return_vals = values;
values[0].type = PARAM_STATUS;
values[0].data.d_status = status;
}
static void
temp_pattern_invoker(char *name,
int nparams,
GParam *param,
int *nreturn_vals,
GParam **return_vals)
{
static GParam values[1];
GStatusType status = STATUS_SUCCESS;
GPatternData *pdata = (GPatternData *)g_hash_table_lookup(gpattern_ht,name);
if(!pdata)
{
g_warning("Can't find internal pattern data");
}
else
{
if(!pdata->busy)
{
pdata->pname = g_strdup(param[0].data.d_string);
pdata->width = param[1].data.d_int32;
pdata->height = param[2].data.d_int32;
pdata->bytes = param[3].data.d_int32;
pdata->pattern_mask_data = g_malloc(param[4].data.d_int32);
g_memmove(pdata->pattern_mask_data,param[5].data.d_int8array,param[4].data.d_int32);
pdata->closing = param[6].data.d_int32;
active_pattern_pdb = pdata;
pdata->busy = 1;
gtk_idle_add((GtkFunction) idle_test_pattern,active_pattern_pdb);
}
}
@ -553,7 +644,10 @@ gen_temp_plugin_name (void)
* selection mech.
*/
void
gimp_interactive_selection_brush(gchar *dialogname, gchar *brush_name,GRunBrushCallback callback)
gimp_interactive_selection_brush(gchar *dialogname,
gchar *brush_name,
GRunBrushCallback callback,
gpointer udata)
{
static GParamDef args[] =
{
@ -618,5 +712,139 @@ gimp_interactive_selection_brush(gchar *dialogname, gchar *brush_name,GRunBrushC
g_str_equal);
bdata->callback = callback;
bdata->udata = udata;
g_hash_table_insert(gbrush_ht,pdbname,bdata);
}
void *
gimp_interactive_selection_pattern(gchar *dialogname,
gchar *pattern_name,
GRunPatternCallback callback,
gpointer udata)
{
static GParamDef args[] =
{
{ PARAM_STRING, "str", "String"},
{ PARAM_INT32, "mask width","pattern width"},
{ PARAM_INT32, "mask height","pattern heigth"},
{ PARAM_INT32, "mask bpp","pattern bytes per pixel"},
{ PARAM_INT32, "mask len","Length of pattern mask data"},
{ PARAM_INT8ARRAY,"mask data","The pattern mask data"},
{ PARAM_INT32, "dialog status","Registers if the dialog was closing [0 = No, 1 = Yes]"},
};
static GParamDef *return_vals = NULL;
static int nargs = sizeof (args) / sizeof (args[0]);
static int nreturn_vals = 0;
gint bnreturn_vals;
GParam *pdbreturn_vals;
gchar *pdbname = gen_temp_plugin_name();
GPatternData *pdata = g_malloc0(sizeof(struct _GPatternData));
gimp_install_temp_proc (pdbname,
"Temp PDB for interactive popups",
"More here later",
"Andy Thomas",
"Andy Thomas",
"1997",
NULL,
"RGB*, GRAY*",
PROC_TEMPORARY,
nargs, nreturn_vals,
args, return_vals,
temp_pattern_invoker);
pdbreturn_vals =
gimp_run_procedure("gimp_patterns_popup",
&bnreturn_vals,
PARAM_STRING,pdbname,
PARAM_STRING,dialogname,
PARAM_STRING,pattern_name,/*name*/
PARAM_END);
gimp_setup_callbacks(); /* New function to allow callbacks to be watched */
gimp_destroy_params (pdbreturn_vals,bnreturn_vals);
/* Now add to hash table so we can find it again */
if(gpattern_ht == NULL)
gpattern_ht = g_hash_table_new (g_str_hash,
g_str_equal);
pdata->callback = callback;
pdata->udata = udata;
g_hash_table_insert(gpattern_ht,pdbname,pdata);
return pdbname;
}
gchar *
gimp_pattern_get_pattern_data (gchar *pname,
gint *width,
gint *height,
gint *bytes,
gchar **mask_data)
{
GParam *return_vals;
int nreturn_vals;
gchar *ret_name = NULL;
return_vals = gimp_run_procedure ("gimp_patterns_get_pattern_data",
&nreturn_vals,
PARAM_STRING, pname,
PARAM_END);
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
ret_name = g_strdup(return_vals[1].data.d_string);
*width = return_vals[2].data.d_int32;
*height = return_vals[3].data.d_int32;
*bytes = return_vals[4].data.d_int32;
*mask_data = g_new (gchar,return_vals[5].data.d_int32);
g_memmove (*mask_data, return_vals[6].data.d_int32array,return_vals[5].data.d_int32);
}
gimp_destroy_params (return_vals, nreturn_vals);
return ret_name;
}
gint
gimp_pattern_close_popup(void * popup_pnt)
{
GParam *return_vals;
int nreturn_vals;
gint retval;
return_vals = gimp_run_procedure ("gimp_patterns_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_pattern_set_popup(void * popup_pnt, gchar * pname)
{
GParam *return_vals;
int nreturn_vals;
gint retval;
return_vals = gimp_run_procedure ("gimp_patterns_set_popup",
&nreturn_vals,
PARAM_STRING, popup_pnt,
PARAM_STRING, pname,
PARAM_END);
gimp_destroy_params (return_vals, nreturn_vals);
retval = (return_vals[0].data.d_status == STATUS_SUCCESS);
return retval;
}

View File

@ -42,7 +42,17 @@ typedef void (* GRunBrushCallback) (gchar *, /* Name */
gint, /* width */
gint, /* height */
gchar *, /* mask data */
gint /* dialog closing */);
gint, /* dialog closing */
gpointer /* user data */);
/* Popup the pattern dialog */
typedef void (*GRunPatternCallback) (gchar *, /* Name */
gint, /* Width */
gint, /* Heigth */
gint, /* bytes pp in mask */
gchar *, /* mask data */
gint, /* dialog closing */
gpointer /* user data */);
GtkWidget* gimp_image_menu_new (GimpConstraintFunc constraint,
GimpMenuCallback callback,
@ -63,7 +73,32 @@ GtkWidget* gimp_drawable_menu_new (GimpConstraintFunc constraint,
void gimp_interactive_selection_brush (gchar *dialogname,
gchar *brush_name,
GRunBrushCallback callback);
GRunBrushCallback callback,
gpointer udata);
void * gimp_interactive_selection_pattern (gchar *dialogtitle,
gchar *pattern_name,
GRunPatternCallback callback,
gpointer udata);
GtkWidget * gimp_pattern_select_widget(gchar * dname,
gchar * ipattern,
GRunPatternCallback cback,
gpointer);
gint gimp_pattern_select_widget_close_popup(GtkWidget *w);
gint gimp_pattern_select_widget_set_popup(GtkWidget *w,gchar *pname);
gchar *gimp_pattern_get_pattern_data (gchar *pname,
gint *width,
gint *height,
gint *bytes,
gchar **mask_data);
gint gimp_pattern_set_popup(void * popup_pnt, gchar * pname);
gint gimp_pattern_close_popup(void * popup_pnt);
#ifdef __cplusplus
}

384
libgimp/gimppatternmenu.c Normal file
View File

@ -0,0 +1,384 @@
/* 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 pattern.
* you get a widget returned that you can use in a table say.
* In:- Initial pattern name. Null means use current selection.
* pointer to func to call when pattern changes (GRubPatternCallback).
* Returned:- Pointer to a widget that you can use in UI.
*
* Widget simply made up of a preview widget (20x20) containing the pattern
* and a button that can be clicked on to change the pattern.
*/
#define PSEL_DATA_KEY "__psel_data"
#define CELL_SIZE 20
#define PREVIEW_EVENT_MASK GDK_EXPOSURE_MASK | \
GDK_BUTTON_PRESS_MASK | \
GDK_BUTTON_RELEASE_MASK | \
GDK_BUTTON1_MOTION_MASK
struct __patterns_sel {
gchar * dname;
GRunPatternCallback cback;
GtkWidget *pattern_preview;
GtkWidget *device_patpopup;
GtkWidget *device_patpreview;
GtkWidget *button;
GtkWidget *top_hbox;
gchar *pattern_name; /* Local copy */
gint width;
gint height;
gint bytes;
gchar *mask_data; /* local copy */
void *pattern_popup_pnt; /* POinter use to control the popup */
gpointer udata;
};
typedef struct __patterns_sel PSelect, * PSelectP;
static void
pattern_popup_open (int x,
int y,
PSelectP psel)
{
gint x_org, y_org;
gint scr_w, scr_h;
gchar *src, *buf;
/* make sure the popup exists and is not visible */
if (psel->device_patpopup == NULL)
{
GtkWidget *frame;
psel->device_patpopup = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_policy (GTK_WINDOW (psel->device_patpopup), FALSE, FALSE, TRUE);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (psel->device_patpopup), frame);
gtk_widget_show (frame);
psel->device_patpreview = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_container_add (GTK_CONTAINER (frame), psel->device_patpreview);
gtk_widget_show (psel->device_patpreview);
}
else
{
gtk_widget_hide (psel->device_patpopup);
}
/* decide where to put the popup */
gdk_window_get_origin (psel->pattern_preview->window, &x_org, &y_org);
scr_w = gdk_screen_width ();
scr_h = gdk_screen_height ();
x = x_org + x - (psel->width >> 1);
y = y_org + y - (psel->height >> 1);
x = (x < 0) ? 0 : x;
y = (y < 0) ? 0 : y;
x = (x + psel->width > scr_w) ? scr_w - psel->width : x;
y = (y + psel->height > scr_h) ? scr_h - psel->height : y;
gtk_preview_size (GTK_PREVIEW (psel->device_patpreview), psel->width, psel->height);
gtk_widget_popup (psel->device_patpopup, x, y);
/* Draw the pattern */
buf = g_new (gchar, psel->width * 3);
src = psel->mask_data;
for (y = 0; y < psel->height; y++)
{
if (psel->bytes == 1)
for (x = 0; x < psel->width; x++)
{
buf[x*3+0] = src[x];
buf[x*3+1] = src[x];
buf[x*3+2] = src[x];
}
else
for (x = 0; x < psel->width; x++)
{
buf[x*3+0] = src[x*3+0];
buf[x*3+1] = src[x*3+1];
buf[x*3+2] = src[x*3+2];
}
gtk_preview_draw_row (GTK_PREVIEW (psel->device_patpreview), (guchar *)buf, 0, y, psel->width);
src += psel->width * psel->bytes;
}
g_free(buf);
/* Draw the brush preview */
gtk_widget_draw (psel->device_patpreview, NULL);
}
static void
pattern_popup_close (PSelectP psel)
{
if (psel->device_patpopup != NULL)
gtk_widget_hide (psel->device_patpopup);
}
static gint
pattern_preview_events (GtkWidget *widget,
GdkEvent *event,
gpointer udata)
{
GdkEventButton *bevent;
PSelectP psel = (PSelectP)udata;
if(psel->mask_data)
{
switch (event->type)
{
case GDK_EXPOSE:
break;
case GDK_BUTTON_PRESS:
bevent = (GdkEventButton *) event;
if (bevent->button == 1)
{
pattern_popup_open (bevent->x, bevent->y, psel);
}
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 */
pattern_popup_close (psel);
}
break;
case GDK_DELETE:
break;
default:
break;
}
}
return FALSE;
}
static void
pattern_pre_update(GtkWidget *pattern_preview,
gint width,
gint height,
gint bytes,
gchar *mask_data)
{
gint x,y;
gchar *src, *buf;
/* Draw the pattern */
buf = g_new (gchar, width * 3);
src = mask_data;
for (y = 0; y< CELL_SIZE && y < height; y++)
{
if (bytes == 1)
for (x = 0; x < width && x < CELL_SIZE; x++)
{
buf[x*3+0] = src[x];
buf[x*3+1] = src[x];
buf[x*3+2] = src[x];
}
else
for (x = 0; x < width && x < CELL_SIZE; x++)
{
buf[x*3+0] = src[x*3+0];
buf[x*3+1] = src[x*3+1];
buf[x*3+2] = src[x*3+2];
}
gtk_preview_draw_row (GTK_PREVIEW (pattern_preview), (guchar *)buf, 0, y, (width < CELL_SIZE)?width:CELL_SIZE);
src += width * bytes;
}
g_free(buf);
/* Draw the brush preview */
gtk_widget_draw (pattern_preview, NULL);
}
static void
pattern_select_invoker(gchar *name,
gint width,
gint height,
gint bytes,
gchar * mask_data,
gint closing,
gpointer udata)
{
gint mask_d_sz;
PSelectP psel = (PSelectP)udata;
if(psel->mask_data != NULL)
g_free(psel->mask_data);
psel->width = width;
psel->height = height;
psel->bytes = bytes;
mask_d_sz = width*height*bytes;
psel->mask_data = g_malloc(mask_d_sz);
g_memmove(psel->mask_data,mask_data,mask_d_sz);
pattern_pre_update(psel->pattern_preview,psel->width,psel->height,psel->bytes,psel->mask_data);
if(psel->cback != NULL)
(psel->cback)(name,width,height,bytes,mask_data,closing,psel->udata);
if(closing)
{
gtk_widget_set_sensitive(psel->button,TRUE);
psel->pattern_popup_pnt = NULL;
}
}
static void
patterns_select_callback (GtkWidget *widget,
gpointer data)
{
PSelectP psel = (PSelectP)data;
gtk_widget_set_sensitive(psel->button,FALSE);
psel->pattern_popup_pnt =
gimp_interactive_selection_pattern((psel->dname)?psel->dname:"Pattern Plugin Selection",
psel->pattern_name,
pattern_select_invoker,psel);
}
GtkWidget *
gimp_pattern_select_widget(gchar *dname,
gchar *ipattern,
GRunPatternCallback cback,
gpointer udata)
{
GtkWidget * frame;
GtkWidget * hbox;
GtkWidget * pattern;
GtkWidget * button;
gint width,height,bytes;
gchar *mask_data;
gchar *pattern_name;
PSelectP psel = g_new(PSelect, sizeof(PSelect));
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);
pattern = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (pattern), CELL_SIZE, CELL_SIZE);
gtk_widget_show(pattern);
gtk_container_add (GTK_CONTAINER (frame), pattern);
gtk_widget_set_events (pattern, PREVIEW_EVENT_MASK);
gtk_signal_connect (GTK_OBJECT (pattern), "event",
(GtkSignalFunc) pattern_preview_events,
(gpointer)psel);
psel->cback = cback;
psel->udata = udata;
psel->mask_data = NULL;
psel->device_patpopup = psel->device_patpreview = NULL;
psel->pattern_preview = pattern;
psel->pattern_name = ipattern;
psel->dname = dname;
psel->pattern_popup_pnt = NULL;
/* Do initial pattern setup */
pattern_name = gimp_pattern_get_pattern_data(ipattern,&width,&height,&bytes,&mask_data);
if(pattern_name)
{
pattern_pre_update(psel->pattern_preview,width,height,bytes,mask_data);
psel->mask_data = mask_data;
psel->pattern_name = pattern_name;
psel->width = width;
psel->height = height;
psel->bytes = bytes;
}
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);
psel->button = button;
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) patterns_select_callback,
(gpointer)psel);
gtk_object_set_data(GTK_OBJECT(hbox),PSEL_DATA_KEY,(gpointer)psel);
return hbox;
}
gint
gimp_pattern_select_widget_close_popup(GtkWidget *w)
{
gint ret_val = FALSE;
PSelectP psel = (PSelectP)gtk_object_get_data(GTK_OBJECT(w),PSEL_DATA_KEY);
if(psel && psel->pattern_popup_pnt)
{
ret_val = gimp_pattern_close_popup(psel->pattern_popup_pnt);
psel->pattern_popup_pnt = NULL;
}
return ret_val;
}
gint
gimp_pattern_select_widget_set_popup(GtkWidget *w,gchar *pname)
{
gint ret_val = FALSE;
gint width,height,bytes;
gchar *mask_data;
gchar *pattern_name;
PSelectP psel = (PSelectP)gtk_object_get_data(GTK_OBJECT(w),PSEL_DATA_KEY);
if(psel)
{
pattern_name = gimp_pattern_get_pattern_data(pname,&width,&height,&bytes,&mask_data);
pattern_select_invoker(pname,width,height,bytes,mask_data,0,psel);
if(psel->pattern_popup_pnt)
{
if(gimp_pattern_set_popup(psel->pattern_popup_pnt,pname))
{
ret_val = TRUE;
}
}
}
return ret_val;
}

View File

@ -3331,6 +3331,7 @@ paint_page()
}
#if 0 /* NOT USED */
static void
gfig_get_brushes(GtkWidget *list)
{
@ -3443,7 +3444,8 @@ gfig_brush_invoker(gchar *name,
gint width,
gint height,
gchar * mask_data,
gint closing)
gint closing,
gpointer udata)
{
BRUSHDESC *bdesc = g_malloc0(sizeof(BRUSHDESC)); /* Mem leak */
@ -3462,7 +3464,7 @@ select_brush_press(GtkWidget *widget,
gpointer data)
{
BRUSHDESC *bdesc = g_malloc0(sizeof(BRUSHDESC));
gimp_interactive_selection_brush("Gfig brush selection",mygimp_brush_get(),gfig_brush_invoker);
gimp_interactive_selection_brush("Gfig brush selection",mygimp_brush_get(),gfig_brush_invoker,NULL);
bdesc->bpp = 3;
bdesc->bname = mygimp_brush_get();

View File

@ -32,7 +32,8 @@ typedef enum
SF_VALUE,
SF_STRING,
SF_ADJUSTMENT,
SF_FONT
SF_FONT,
SF_PATTERN
} SFArgType;
typedef enum

View File

@ -79,6 +79,7 @@ typedef union
gchar * sfa_value;
SFAdjustment sfa_adjustment;
SFFont sfa_font;
gchar * sfa_pattern;
} SFArgValue;
typedef struct
@ -166,6 +167,16 @@ static void script_fu_about_dialog_close (GtkWidget *widget,
static gint script_fu_about_dialog_delete (GtkWidget *widget,
GdkEvent *event,
gpointer data);
static void script_fu_pattern_preview (gchar *name,
gint width,
gint height,
gint bytes,
gchar * mask_data,
gint closing,
gpointer udata);
/*
* Local variables
@ -549,7 +560,18 @@ script_fu_add_script (LISP a)
args[i + 1].name = "font";
args[i + 1].description = script->arg_labels[i];
break;
case SF_PATTERN:
if (!TYPEP (car (a), tc_string))
return my_err ("script-fu-register: pattern defaults must be string values", NIL);
script->arg_defaults[i].sfa_pattern = g_strdup (get_c_string (car (a)));
script->arg_values[i].sfa_pattern = g_strdup (script->arg_defaults[i].sfa_pattern);
args[i + 1].type = PARAM_STRING;
args[i + 1].name = "pattern";
args[i + 1].description = script->arg_labels[i];
break;
break;
default:
@ -700,6 +722,9 @@ script_fu_script_proc (char *name,
case SF_FONT:
length += strlen (params[i + 1].data.d_string) + 3;
break;
case SF_PATTERN:
length += strlen (params[i + 1].data.d_string) + 3;
break;
default:
break;
}
@ -746,6 +771,10 @@ script_fu_script_proc (char *name,
g_snprintf (buffer, MAX_STRING_LENGTH, "\"%s\"", params[i + 1].data.d_string);
text = buffer;
break;
case SF_PATTERN:
g_snprintf (buffer, MAX_STRING_LENGTH, "\"%s\"", params[i + 1].data.d_string);
text = buffer;
break;
default:
break;
}
@ -839,6 +868,9 @@ script_fu_free_script (SFScript *script)
g_free (script->arg_defaults[i].sfa_font.fontname);
g_free (script->arg_values[i].sfa_font.fontname);
break;
case SF_PATTERN:
g_free (script->arg_defaults[i].sfa_pattern);
g_free (script->arg_values[i].sfa_pattern);
default:
break;
}
@ -1093,6 +1125,13 @@ script_fu_interface (SFScript *script)
(GtkSignalFunc) script_fu_font_preview_callback,
&script->arg_values[i].sfa_font);
break;
case SF_PATTERN:
script->args_widgets[i] = gimp_pattern_select_widget("Script-fu Pattern Selection",
script->arg_values[i].sfa_pattern,
script_fu_pattern_preview,
&script->arg_values[i].sfa_pattern);
break;
default:
break;
}
@ -1104,7 +1143,7 @@ script_fu_interface (SFScript *script)
gtk_table_attach (GTK_TABLE (table), hbox, /* script->args_widgets[i], */
1, 2, i, i + 1,
GTK_FILL | (((script->arg_types[i] == SF_VALUE) || (script->arg_types[i] == SF_STRING) || (script->arg_types[i] == SF_FONT))
GTK_FILL | (((script->arg_types[i] == SF_VALUE) || (script->arg_types[i] == SF_STRING) || (script->arg_types[i] == SF_FONT))
? GTK_EXPAND : 0),
GTK_FILL, 4, 2);
gtk_widget_show (script->args_widgets[i]);
@ -1196,6 +1235,22 @@ script_fu_color_preview (GtkWidget *preview,
gtk_widget_draw (preview, NULL);
}
static void
script_fu_pattern_preview(gchar *name,
gint width,
gint height,
gint bytes,
gchar * mask_data,
gint closing,
gpointer udata)
{
gchar ** pname = (gchar **) udata;
g_free(*pname);
*pname = g_strdup(name);
}
static void
script_fu_font_preview (GtkWidget *preview,
gchar *data)
@ -1262,6 +1317,9 @@ script_fu_cleanup_widgets (SFScript *script)
script->arg_values[i].sfa_font.dialog = NULL;
}
break;
case SF_PATTERN:
gimp_pattern_select_widget_close_popup(script->args_widgets[i]);
break;
default:
break;
}
@ -1325,6 +1383,9 @@ script_fu_ok_callback (GtkWidget *widget,
case SF_FONT:
length += strlen (script->arg_values[i].sfa_font.fontname) + 3;
break;
case SF_PATTERN:
length += strlen (script->arg_values[i].sfa_pattern) + 3;
break;
default:
break;
}
@ -1387,6 +1448,10 @@ script_fu_ok_callback (GtkWidget *widget,
g_snprintf (buffer, MAX_STRING_LENGTH, "\"%s\"", script->arg_values[i].sfa_font.fontname);
text = buffer;
break;
case SF_PATTERN:
g_snprintf (buffer, MAX_STRING_LENGTH, "\"%s\"",script->arg_values[i].sfa_pattern);
text = buffer;
break;
default:
break;
}
@ -1621,6 +1686,9 @@ script_fu_reset_callback (GtkWidget *widget,
script_fu_font_preview (script->arg_values[i].sfa_font.preview,
script->arg_values[i].sfa_font.fontname);
break;
case SF_PATTERN:
gimp_pattern_select_widget_set_popup(script->args_widgets[i],script->arg_defaults[i].sfa_pattern);
break;
default:
break;
}

View File

@ -79,6 +79,7 @@ typedef union
gchar * sfa_value;
SFAdjustment sfa_adjustment;
SFFont sfa_font;
gchar * sfa_pattern;
} SFArgValue;
typedef struct
@ -166,6 +167,16 @@ static void script_fu_about_dialog_close (GtkWidget *widget,
static gint script_fu_about_dialog_delete (GtkWidget *widget,
GdkEvent *event,
gpointer data);
static void script_fu_pattern_preview (gchar *name,
gint width,
gint height,
gint bytes,
gchar * mask_data,
gint closing,
gpointer udata);
/*
* Local variables
@ -549,7 +560,18 @@ script_fu_add_script (LISP a)
args[i + 1].name = "font";
args[i + 1].description = script->arg_labels[i];
break;
case SF_PATTERN:
if (!TYPEP (car (a), tc_string))
return my_err ("script-fu-register: pattern defaults must be string values", NIL);
script->arg_defaults[i].sfa_pattern = g_strdup (get_c_string (car (a)));
script->arg_values[i].sfa_pattern = g_strdup (script->arg_defaults[i].sfa_pattern);
args[i + 1].type = PARAM_STRING;
args[i + 1].name = "pattern";
args[i + 1].description = script->arg_labels[i];
break;
break;
default:
@ -700,6 +722,9 @@ script_fu_script_proc (char *name,
case SF_FONT:
length += strlen (params[i + 1].data.d_string) + 3;
break;
case SF_PATTERN:
length += strlen (params[i + 1].data.d_string) + 3;
break;
default:
break;
}
@ -746,6 +771,10 @@ script_fu_script_proc (char *name,
g_snprintf (buffer, MAX_STRING_LENGTH, "\"%s\"", params[i + 1].data.d_string);
text = buffer;
break;
case SF_PATTERN:
g_snprintf (buffer, MAX_STRING_LENGTH, "\"%s\"", params[i + 1].data.d_string);
text = buffer;
break;
default:
break;
}
@ -839,6 +868,9 @@ script_fu_free_script (SFScript *script)
g_free (script->arg_defaults[i].sfa_font.fontname);
g_free (script->arg_values[i].sfa_font.fontname);
break;
case SF_PATTERN:
g_free (script->arg_defaults[i].sfa_pattern);
g_free (script->arg_values[i].sfa_pattern);
default:
break;
}
@ -1093,6 +1125,13 @@ script_fu_interface (SFScript *script)
(GtkSignalFunc) script_fu_font_preview_callback,
&script->arg_values[i].sfa_font);
break;
case SF_PATTERN:
script->args_widgets[i] = gimp_pattern_select_widget("Script-fu Pattern Selection",
script->arg_values[i].sfa_pattern,
script_fu_pattern_preview,
&script->arg_values[i].sfa_pattern);
break;
default:
break;
}
@ -1104,7 +1143,7 @@ script_fu_interface (SFScript *script)
gtk_table_attach (GTK_TABLE (table), hbox, /* script->args_widgets[i], */
1, 2, i, i + 1,
GTK_FILL | (((script->arg_types[i] == SF_VALUE) || (script->arg_types[i] == SF_STRING) || (script->arg_types[i] == SF_FONT))
GTK_FILL | (((script->arg_types[i] == SF_VALUE) || (script->arg_types[i] == SF_STRING) || (script->arg_types[i] == SF_FONT))
? GTK_EXPAND : 0),
GTK_FILL, 4, 2);
gtk_widget_show (script->args_widgets[i]);
@ -1196,6 +1235,22 @@ script_fu_color_preview (GtkWidget *preview,
gtk_widget_draw (preview, NULL);
}
static void
script_fu_pattern_preview(gchar *name,
gint width,
gint height,
gint bytes,
gchar * mask_data,
gint closing,
gpointer udata)
{
gchar ** pname = (gchar **) udata;
g_free(*pname);
*pname = g_strdup(name);
}
static void
script_fu_font_preview (GtkWidget *preview,
gchar *data)
@ -1262,6 +1317,9 @@ script_fu_cleanup_widgets (SFScript *script)
script->arg_values[i].sfa_font.dialog = NULL;
}
break;
case SF_PATTERN:
gimp_pattern_select_widget_close_popup(script->args_widgets[i]);
break;
default:
break;
}
@ -1325,6 +1383,9 @@ script_fu_ok_callback (GtkWidget *widget,
case SF_FONT:
length += strlen (script->arg_values[i].sfa_font.fontname) + 3;
break;
case SF_PATTERN:
length += strlen (script->arg_values[i].sfa_pattern) + 3;
break;
default:
break;
}
@ -1387,6 +1448,10 @@ script_fu_ok_callback (GtkWidget *widget,
g_snprintf (buffer, MAX_STRING_LENGTH, "\"%s\"", script->arg_values[i].sfa_font.fontname);
text = buffer;
break;
case SF_PATTERN:
g_snprintf (buffer, MAX_STRING_LENGTH, "\"%s\"",script->arg_values[i].sfa_pattern);
text = buffer;
break;
default:
break;
}
@ -1621,6 +1686,9 @@ script_fu_reset_callback (GtkWidget *widget,
script_fu_font_preview (script->arg_values[i].sfa_font.preview,
script->arg_values[i].sfa_font.fontname);
break;
case SF_PATTERN:
gimp_pattern_select_widget_set_popup(script->args_widgets[i],script->arg_defaults[i].sfa_pattern);
break;
default:
break;
}

View File

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

View File

@ -30,7 +30,7 @@
;
(define (script-fu-test-sphere radius light shadow bg-color sphere-color text font size)
(define (script-fu-test-sphere radius light shadow bg-color sphere-color text pattern font size)
(let* ((width (* radius 3.75))
(height (* radius 2.5))
(img (car (gimp-image-new width height RGB)))
@ -65,7 +65,8 @@
(prog1 (set! shadow-x (+ cx shadow-w))
(set! shadow-w (- shadow-w))))
(gimp-ellipse-select img shadow-x shadow-y shadow-w shadow-h REPLACE TRUE TRUE 7.5)
(gimp-bucket-fill img drawable BG-BUCKET-FILL MULTIPLY 100 0 FALSE 0 0)))
(gimp-patterns-set-pattern pattern)
(gimp-bucket-fill img drawable PATTERN-BUCKET-FILL MULTIPLY 100 0 FALSE 0 0)))
(gimp-ellipse-select img (- cx radius) (- cy radius) (* 2 radius) (* 2 radius) REPLACE TRUE FALSE 0)
(gimp-blend img drawable FG-BG-RGB NORMAL RADIAL 100 offset REPEAT-NONE
FALSE 0 0 light-x light-y light-end-x light-end-y)
@ -97,6 +98,7 @@
SF-COLOR "Background Color" '(255 255 255)
SF-COLOR "Sphere Color" '(255 0 0)
SF-STRING "Text" "Script-Fu rocks!"
SF-PATTERN "Pattern" "Maple Leaves"
SF-FONT "Font" "-freefont-agate-normal-r-normal-*-24-*-*-*-p-*-*-*"
SF-ADJUSTMENT "Font size (in pixels)" '(50 1 1000 1 10 0 1))