1997-11-25 06:05:25 +08:00
|
|
|
/* The GIMP -- an image manipulation program
|
|
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
1998-04-13 13:44:11 +08:00
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
1997-11-25 06:05:25 +08:00
|
|
|
*/
|
|
|
|
#include <string.h>
|
1999-10-27 02:27:27 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
#include "appenv.h"
|
1999-10-27 02:27:27 +08:00
|
|
|
#include "dialog_handler.h"
|
|
|
|
#include "gimpcontext.h"
|
1999-10-28 23:05:49 +08:00
|
|
|
#include "gimpdnd.h"
|
1999-10-27 02:27:27 +08:00
|
|
|
#include "gimpui.h"
|
1997-11-25 06:05:25 +08:00
|
|
|
#include "patterns.h"
|
|
|
|
#include "pattern_select.h"
|
1998-06-23 01:30:40 +08:00
|
|
|
#include "session.h"
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1998-12-16 08:37:09 +08:00
|
|
|
#include "libgimp/gimpintl.h"
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-04-29 16:50:22 +08:00
|
|
|
#define MIN_CELL_SIZE 32
|
|
|
|
#define MAX_CELL_SIZE 45
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
#define STD_PATTERN_COLUMNS 6
|
|
|
|
#define STD_PATTERN_ROWS 5
|
|
|
|
|
1999-05-02 05:37:34 +08:00
|
|
|
/* how long to wait after mouse-down before showing pattern popup */
|
|
|
|
#define POPUP_DELAY_MS 150
|
|
|
|
|
1998-10-02 06:09:01 +08:00
|
|
|
#define MAX_WIN_WIDTH(psp) (MIN_CELL_SIZE * (psp)->NUM_PATTERN_COLUMNS)
|
|
|
|
#define MAX_WIN_HEIGHT(psp) (MIN_CELL_SIZE * (psp)->NUM_PATTERN_ROWS)
|
1997-11-25 06:05:25 +08:00
|
|
|
#define MARGIN_WIDTH 1
|
|
|
|
#define MARGIN_HEIGHT 1
|
1999-10-27 02:27:27 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
#define PATTERN_EVENT_MASK GDK_BUTTON1_MOTION_MASK | \
|
|
|
|
GDK_EXPOSURE_MASK | \
|
|
|
|
GDK_BUTTON_PRESS_MASK | \
|
|
|
|
GDK_ENTER_NOTIFY_MASK
|
|
|
|
|
|
|
|
/* local function prototypes */
|
1999-10-28 23:05:49 +08:00
|
|
|
static void pattern_change_callbacks (PatternSelect *psp,
|
|
|
|
gboolean closing);
|
|
|
|
|
|
|
|
static void pattern_select_drop_pattern (GtkWidget *widget,
|
|
|
|
GPattern *pattern,
|
|
|
|
gpointer data);
|
1999-10-27 02:27:27 +08:00
|
|
|
static void pattern_select_pattern_changed (GimpContext *context,
|
|
|
|
GPattern *pattern,
|
|
|
|
PatternSelect *psp);
|
|
|
|
static void pattern_select_select (PatternSelect *psp,
|
|
|
|
gint index);
|
|
|
|
|
|
|
|
static gboolean pattern_popup_timeout (gpointer data);
|
|
|
|
static void pattern_popup_open (PatternSelect *psp,
|
|
|
|
gint, gint, GPattern *);
|
|
|
|
static void pattern_popup_close (PatternSelect *);
|
|
|
|
|
|
|
|
static void display_setup (PatternSelect *);
|
|
|
|
static void display_pattern (PatternSelect *, GPattern *,
|
|
|
|
gint, gint);
|
|
|
|
static void display_patterns (PatternSelect *);
|
|
|
|
|
|
|
|
static void pattern_select_show_selected (PatternSelect *, gint, gint);
|
|
|
|
static void update_active_pattern_field (PatternSelect *);
|
|
|
|
static void preview_calc_scrollbar (PatternSelect *);
|
|
|
|
|
|
|
|
static gint pattern_select_resize (GtkWidget *, GdkEvent *,
|
|
|
|
PatternSelect *);
|
|
|
|
static gint pattern_select_events (GtkWidget *, GdkEvent *,
|
|
|
|
PatternSelect *);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
static void pattern_select_scroll_update (GtkAdjustment *, gpointer);
|
|
|
|
|
|
|
|
static void pattern_select_close_callback (GtkWidget *, gpointer);
|
|
|
|
static void pattern_select_refresh_callback (GtkWidget *, gpointer);
|
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
/* dnd stuff */
|
|
|
|
static GtkTargetEntry preview_target_table[] =
|
|
|
|
{
|
|
|
|
GIMP_TARGET_PATTERN
|
|
|
|
};
|
|
|
|
static guint preview_n_targets = (sizeof (preview_target_table) /
|
|
|
|
sizeof (preview_target_table[0]));
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
/* The main pattern selection dialog */
|
|
|
|
PatternSelect *pattern_select_dialog = NULL;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-04-23 22:47:50 +08:00
|
|
|
/* local variables */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-04-23 22:47:50 +08:00
|
|
|
/* List of active dialogs */
|
gave parasite undo a MISC_UNDO class for now so it compiles
* app/gimpdrawable.c: gave parasite undo a MISC_UNDO class for now
so it compiles
* app/tools_cmds.c: fix crop invoker to give correct args to
crop_image
* app/color_cmds.c: s/GRAY/GRAY_LUT/g;
* app/brush_select.[ch]: removed PDB procs, export brush_active_dialogs,
brush_select_dialog, s/active_dialogs/brush_active_dialogs/
* app/gimage_cmds.[ch]
* app/channel_ops.[ch]: removed channel ops PDB procs, moved duplicate
function from gimage_cmds to channel_ops, export offset and duplicate
* app/gimpbrushlist.[ch]: removed PDB procs
* app/gradient.[ch]: removed PDB procs,
* app/gradient_header.h: exported G_SAMPLE, GradSelect, num_gradients,
grad_active_dialogs, gradient_select_dialog
* app/gradient_select.c: removed PDB procs,
s/active_dialogs/grad_active_dialogs/
* app/patterns.[ch]: removed PDB procs
* app/pattern_select.[ch]: removed PDB procs,
s/active_dialogs/pattern_active_dialogs/
* app/procedural_db.c: removed PDB procs and supporting functions
* app/procedrual_db.h: fiddled with enums
* app/channel_cmds.[ch]
* app/drawable_cmds.[ch]
* app/parasite_cmds.[ch]: pdbgenned now, removed header files
* app/gimpparasite.c: minor cleanup
* app/internal_procs.c: use pdbgen stuff
* app/tools_cmds.c
* app/text_tool_cmds.c: updated from pdbgen
* app/brushes_cmds.c
* app/brush_select_cmds.c
* app/gradient_cmds.c
* app/gradient_select_cmds.c
* app/patterns_cmds.c
* app/pattern_select_cmds.c
* app/procedural_db_cmds.c: new pdbgen files
* app/Makefile.am: file shuffle (see above)
-Yosh
1999-04-24 04:54:02 +08:00
|
|
|
GSList *pattern_active_dialogs = NULL;
|
1998-10-02 06:09:01 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
void
|
|
|
|
pattern_dialog_create (void)
|
|
|
|
{
|
|
|
|
if (! pattern_select_dialog)
|
|
|
|
{
|
|
|
|
pattern_select_dialog = pattern_select_new (NULL, NULL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!GTK_WIDGET_VISIBLE (pattern_select_dialog->shell))
|
|
|
|
gtk_widget_show (pattern_select_dialog->shell);
|
|
|
|
else
|
|
|
|
gdk_window_raise (pattern_select_dialog->shell->window);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
pattern_dialog_free ()
|
|
|
|
{
|
|
|
|
if (pattern_select_dialog)
|
|
|
|
{
|
1999-10-28 23:05:49 +08:00
|
|
|
session_get_window_info (pattern_select_dialog->shell,
|
|
|
|
&pattern_select_session_info);
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
pattern_select_free (pattern_select_dialog);
|
|
|
|
pattern_select_dialog = NULL;
|
|
|
|
}
|
|
|
|
}
|
1999-04-23 22:47:50 +08:00
|
|
|
|
|
|
|
/* If title == NULL then it is the main pattern dialog */
|
1999-10-27 02:27:27 +08:00
|
|
|
PatternSelect *
|
1999-04-23 22:47:50 +08:00
|
|
|
pattern_select_new (gchar *title,
|
|
|
|
gchar *initial_pattern)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
PatternSelect *psp;
|
1997-11-25 06:05:25 +08:00
|
|
|
GtkWidget *vbox;
|
|
|
|
GtkWidget *hbox;
|
1999-04-23 22:47:50 +08:00
|
|
|
GtkWidget *frame;
|
1997-11-25 06:05:25 +08:00
|
|
|
GtkWidget *sbar;
|
|
|
|
GtkWidget *label_box;
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
GPattern *active = NULL;
|
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
static gboolean first_call = TRUE;
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
psp = g_new (PatternSelect, 1);
|
|
|
|
psp->preview = NULL;
|
|
|
|
psp->callback_name = NULL;
|
|
|
|
psp->pattern_popup = NULL;
|
|
|
|
psp->popup_timeout_tag = 0;
|
|
|
|
psp->old_col = 0;
|
|
|
|
psp->old_row = 0;
|
1999-04-29 16:50:22 +08:00
|
|
|
psp->NUM_PATTERN_COLUMNS = STD_PATTERN_COLUMNS;
|
|
|
|
psp->NUM_PATTERN_ROWS = STD_PATTERN_COLUMNS;
|
1998-10-02 06:09:01 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
/* The shell */
|
|
|
|
psp->shell = gimp_dialog_new (title ? title : _("Pattern Selection"),
|
|
|
|
"pattern_selection",
|
|
|
|
gimp_standard_help_func,
|
|
|
|
"dialogs/pattern_selection.html",
|
|
|
|
GTK_WIN_POS_NONE,
|
|
|
|
FALSE, TRUE, FALSE,
|
1999-09-28 01:58:10 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
_("Refresh"), pattern_select_refresh_callback,
|
|
|
|
psp, NULL, FALSE, FALSE,
|
|
|
|
_("Close"), pattern_select_close_callback,
|
|
|
|
psp, NULL, TRUE, TRUE,
|
1999-09-28 01:58:10 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
NULL);
|
1999-09-28 01:58:10 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
if (title)
|
|
|
|
{
|
|
|
|
psp->context = gimp_context_new (title, NULL);
|
1998-10-02 06:09:01 +08:00
|
|
|
}
|
1999-09-28 01:58:10 +08:00
|
|
|
else
|
|
|
|
{
|
1999-10-28 23:05:49 +08:00
|
|
|
psp->context = gimp_context_get_user ();
|
1999-09-28 01:58:10 +08:00
|
|
|
|
|
|
|
session_set_window_geometry (psp->shell, &pattern_select_session_info,
|
|
|
|
TRUE);
|
1999-10-28 23:05:49 +08:00
|
|
|
dialog_register (psp->shell);
|
1999-10-27 02:27:27 +08:00
|
|
|
}
|
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
if (no_data && first_call)
|
1999-10-27 02:27:27 +08:00
|
|
|
patterns_init (FALSE);
|
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
first_call = FALSE;
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
if (title && initial_pattern && strlen (initial_pattern))
|
|
|
|
{
|
|
|
|
active = pattern_list_get_pattern (pattern_list, initial_pattern);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
active = gimp_context_get_pattern (gimp_context_get_user ());
|
1999-09-28 01:58:10 +08:00
|
|
|
}
|
1998-10-02 06:09:01 +08:00
|
|
|
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
if (!active)
|
1999-10-27 02:27:27 +08:00
|
|
|
{
|
|
|
|
active = gimp_context_get_pattern (gimp_context_get_standard ());
|
|
|
|
}
|
1998-10-02 06:09:01 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
if (title)
|
|
|
|
{
|
|
|
|
gimp_context_set_pattern (psp->context, active);
|
|
|
|
}
|
1998-10-02 06:09:01 +08:00
|
|
|
|
1999-04-29 16:50:22 +08:00
|
|
|
/* The main vbox */
|
|
|
|
vbox = gtk_vbox_new (FALSE, 0);
|
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
|
|
|
|
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (psp->shell)->vbox), vbox);
|
|
|
|
|
|
|
|
/* Options box */
|
|
|
|
psp->options_box = gtk_vbox_new (FALSE, 0);
|
1997-11-25 06:05:25 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), psp->options_box, FALSE, FALSE, 0);
|
|
|
|
|
|
|
|
/* Create the active pattern label */
|
1999-04-29 16:50:22 +08:00
|
|
|
label_box = gtk_hbox_new (FALSE, 0);
|
|
|
|
gtk_box_pack_start (GTK_BOX (psp->options_box), label_box, FALSE, FALSE, 2);
|
|
|
|
|
1998-12-16 08:37:09 +08:00
|
|
|
psp->pattern_name = gtk_label_new (_("Active"));
|
1999-04-29 16:50:22 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (label_box), psp->pattern_name, FALSE, FALSE, 4);
|
1999-04-23 22:47:50 +08:00
|
|
|
psp->pattern_size = gtk_label_new ("(0 X 0)");
|
1999-04-29 16:50:22 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (label_box), psp->pattern_size, FALSE, FALSE, 2);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
gtk_widget_show (psp->pattern_name);
|
|
|
|
gtk_widget_show (psp->pattern_size);
|
|
|
|
gtk_widget_show (label_box);
|
|
|
|
|
|
|
|
/* The horizontal box containing preview & scrollbar */
|
1999-10-27 02:27:27 +08:00
|
|
|
hbox = gtk_hbox_new (FALSE, 2);
|
1997-11-25 06:05:25 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
|
1999-10-27 02:27:27 +08:00
|
|
|
|
1999-04-23 22:47:50 +08:00
|
|
|
frame = gtk_frame_new (NULL);
|
|
|
|
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
psp->sbar_data =
|
|
|
|
GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, MAX_WIN_HEIGHT(psp),
|
|
|
|
1, 1, MAX_WIN_HEIGHT(psp)));
|
|
|
|
sbar = gtk_vscrollbar_new (psp->sbar_data);
|
1997-11-25 06:05:25 +08:00
|
|
|
gtk_signal_connect (GTK_OBJECT (psp->sbar_data), "value_changed",
|
1999-10-27 02:27:27 +08:00
|
|
|
GTK_SIGNAL_FUNC (pattern_select_scroll_update),
|
1997-11-25 06:05:25 +08:00
|
|
|
psp);
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), sbar, FALSE, FALSE, 0);
|
|
|
|
|
|
|
|
/* Create the pattern preview window and the underlying image */
|
1999-04-23 22:47:50 +08:00
|
|
|
|
|
|
|
/* Get the initial pattern extents */
|
1999-10-27 02:27:27 +08:00
|
|
|
psp->cell_width = MIN_CELL_SIZE;
|
1999-04-29 16:50:22 +08:00
|
|
|
psp->cell_height = MIN_CELL_SIZE;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
psp->preview = gtk_preview_new (GTK_PREVIEW_COLOR);
|
1999-04-23 22:47:50 +08:00
|
|
|
gtk_preview_size (GTK_PREVIEW (psp->preview),
|
|
|
|
MAX_WIN_WIDTH (psp), MAX_WIN_HEIGHT (psp));
|
|
|
|
gtk_preview_set_expand (GTK_PREVIEW (psp->preview), TRUE);
|
1997-11-25 06:05:25 +08:00
|
|
|
gtk_widget_set_events (psp->preview, PATTERN_EVENT_MASK);
|
|
|
|
|
|
|
|
gtk_signal_connect (GTK_OBJECT (psp->preview), "event",
|
1999-10-27 02:27:27 +08:00
|
|
|
GTK_SIGNAL_FUNC (pattern_select_events),
|
1997-11-25 06:05:25 +08:00
|
|
|
psp);
|
1999-04-23 22:47:50 +08:00
|
|
|
gtk_signal_connect (GTK_OBJECT (psp->preview), "size_allocate",
|
1999-10-27 02:27:27 +08:00
|
|
|
GTK_SIGNAL_FUNC (pattern_select_resize),
|
1999-04-23 22:47:50 +08:00
|
|
|
psp);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
/* dnd stuff */
|
|
|
|
gtk_drag_dest_set (psp->preview,
|
|
|
|
GTK_DEST_DEFAULT_ALL,
|
|
|
|
preview_target_table, preview_n_targets,
|
|
|
|
GDK_ACTION_COPY);
|
|
|
|
gimp_dnd_pattern_dest_set (psp->preview, pattern_select_drop_pattern, psp);
|
|
|
|
|
1999-04-23 22:47:50 +08:00
|
|
|
gtk_container_add (GTK_CONTAINER (frame), psp->preview);
|
1997-11-25 06:05:25 +08:00
|
|
|
gtk_widget_show (psp->preview);
|
|
|
|
|
|
|
|
gtk_widget_show (sbar);
|
|
|
|
gtk_widget_show (hbox);
|
1999-04-23 22:47:50 +08:00
|
|
|
gtk_widget_show (frame);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
gtk_widget_show (psp->options_box);
|
|
|
|
gtk_widget_show (vbox);
|
|
|
|
gtk_widget_show (psp->shell);
|
|
|
|
|
|
|
|
preview_calc_scrollbar (psp);
|
1999-10-27 02:27:27 +08:00
|
|
|
|
|
|
|
gtk_signal_connect (GTK_OBJECT (psp->context), "pattern_changed",
|
|
|
|
GTK_SIGNAL_FUNC (pattern_select_pattern_changed),
|
|
|
|
psp);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
if (active)
|
|
|
|
pattern_select_select (psp, active->index);
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
/* Add to active pattern dialogs list */
|
|
|
|
pattern_active_dialogs = g_slist_append (pattern_active_dialogs, psp);
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
return psp;
|
|
|
|
}
|
|
|
|
|
1998-10-02 06:09:01 +08:00
|
|
|
void
|
1999-10-27 02:27:27 +08:00
|
|
|
pattern_select_free (PatternSelect *psp)
|
|
|
|
{
|
|
|
|
if (!psp)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* remove from active list */
|
|
|
|
pattern_active_dialogs = g_slist_remove (pattern_active_dialogs, psp);
|
|
|
|
|
|
|
|
gtk_signal_disconnect_by_data (GTK_OBJECT (psp->context), psp);
|
|
|
|
|
|
|
|
if (psp->pattern_popup != NULL)
|
|
|
|
gtk_widget_destroy (psp->pattern_popup);
|
|
|
|
|
|
|
|
if (psp->popup_timeout_tag != 0)
|
|
|
|
gtk_timeout_remove (psp->popup_timeout_tag);
|
|
|
|
|
|
|
|
if (psp->callback_name)
|
|
|
|
{
|
|
|
|
g_free (psp->callback_name);
|
|
|
|
gtk_object_unref (GTK_OBJECT (psp->context));
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (psp);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Call this dialog's PDB callback */
|
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
static void
|
1999-10-27 02:27:27 +08:00
|
|
|
pattern_change_callbacks (PatternSelect *psp,
|
1999-10-28 23:05:49 +08:00
|
|
|
gboolean closing)
|
1998-10-02 06:09:01 +08:00
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
gchar *name;
|
1998-10-02 06:09:01 +08:00
|
|
|
ProcRecord *prec = NULL;
|
|
|
|
GPatternP pattern;
|
1999-10-27 02:27:27 +08:00
|
|
|
gint nreturn_vals;
|
|
|
|
static gboolean busy = FALSE;
|
1998-10-02 06:09:01 +08:00
|
|
|
|
|
|
|
/* Any procs registered to callback? */
|
|
|
|
Argument *return_vals;
|
1999-10-27 02:27:27 +08:00
|
|
|
|
|
|
|
if (!psp || !psp->callback_name || busy)
|
1998-10-02 06:09:01 +08:00
|
|
|
return;
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
busy = TRUE;
|
1998-10-02 06:09:01 +08:00
|
|
|
name = psp->callback_name;
|
1999-10-27 02:27:27 +08:00
|
|
|
pattern = gimp_context_get_pattern (psp->context);
|
1998-10-02 06:09:01 +08:00
|
|
|
|
|
|
|
/* If its still registered run it */
|
1999-10-27 02:27:27 +08:00
|
|
|
prec = procedural_db_lookup (name);
|
1998-10-02 06:09:01 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
if (prec && pattern)
|
1998-10-02 06:09:01 +08:00
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
return_vals =
|
|
|
|
procedural_db_run_proc (name,
|
|
|
|
&nreturn_vals,
|
1999-10-28 23:05:49 +08:00
|
|
|
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,
|
1999-10-27 02:27:27 +08:00
|
|
|
PDB_INT8ARRAY, temp_buf_data (pattern->mask),
|
1999-10-28 23:05:49 +08:00
|
|
|
PDB_INT32, (gint) closing,
|
1999-10-27 02:27:27 +08:00
|
|
|
PDB_END);
|
1998-10-02 06:09:01 +08:00
|
|
|
|
|
|
|
if (!return_vals || return_vals[0].value.pdb_int != PDB_SUCCESS)
|
1999-06-06 07:41:45 +08:00
|
|
|
g_warning ("failed to run pattern callback function");
|
1998-10-02 06:09:01 +08:00
|
|
|
|
|
|
|
procedural_db_destroy_args (return_vals, nreturn_vals);
|
|
|
|
}
|
1999-10-27 02:27:27 +08:00
|
|
|
busy = FALSE;
|
1998-10-02 06:09:01 +08:00
|
|
|
}
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
/* Close active dialogs that no longer have PDB registered for them */
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
void
|
1999-10-27 02:27:27 +08:00
|
|
|
patterns_check_dialogs (void)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
PatternSelect *psp;
|
|
|
|
GSList *list;
|
|
|
|
gchar *name;
|
|
|
|
ProcRecord *prec = NULL;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
list = pattern_active_dialogs;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
while (list)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
psp = (PatternSelect *) list->data;
|
1999-10-28 23:05:49 +08:00
|
|
|
list = g_slist_next (list);
|
1998-10-02 06:09:01 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
name = psp->callback_name;
|
1998-10-02 06:09:01 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
if (name)
|
|
|
|
{
|
|
|
|
prec = procedural_db_lookup (name);
|
1998-10-02 06:09:01 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
if (!prec)
|
|
|
|
{
|
|
|
|
/* Can alter pattern_active_dialogs list */
|
|
|
|
pattern_select_close_callback (NULL, psp);
|
|
|
|
}
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Local functions
|
|
|
|
*/
|
1999-05-02 05:37:34 +08:00
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
static void
|
|
|
|
pattern_select_drop_pattern (GtkWidget *widget,
|
|
|
|
GPattern *pattern,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
PatternSelect *psp;
|
|
|
|
|
|
|
|
psp = (PatternSelect *) data;
|
|
|
|
|
|
|
|
gimp_context_set_pattern (psp->context, pattern);
|
|
|
|
}
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
static void
|
|
|
|
pattern_select_pattern_changed (GimpContext *context,
|
|
|
|
GPattern *pattern,
|
|
|
|
PatternSelect *psp)
|
|
|
|
{
|
|
|
|
if (pattern)
|
|
|
|
pattern_select_select (psp, pattern->index);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
pattern_select_select (PatternSelect *psp,
|
|
|
|
gint index)
|
|
|
|
{
|
|
|
|
gint row, col;
|
1999-10-28 23:05:49 +08:00
|
|
|
gint scroll_offset = 0;
|
1999-10-27 02:27:27 +08:00
|
|
|
|
|
|
|
update_active_pattern_field (psp);
|
|
|
|
|
|
|
|
row = index / psp->NUM_PATTERN_COLUMNS;
|
|
|
|
col = index - row * psp->NUM_PATTERN_COLUMNS;
|
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
/* check if the new active pattern is already in the preview */
|
|
|
|
if (((row + 1) * psp->cell_height) >
|
|
|
|
(psp->preview->allocation.height + psp->scroll_offset))
|
|
|
|
{
|
|
|
|
scroll_offset = (((row + 1) * psp->cell_height) -
|
|
|
|
(psp->scroll_offset + psp->preview->allocation.height));
|
|
|
|
}
|
|
|
|
else if ((row * psp->cell_height) < psp->scroll_offset)
|
|
|
|
{
|
|
|
|
scroll_offset = (row * psp->cell_height) - psp->scroll_offset;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pattern_select_show_selected (psp, row, col);
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_adjustment_set_value (psp->sbar_data, psp->scroll_offset + scroll_offset);
|
1999-10-27 02:27:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
PatternSelect *psp;
|
1999-05-02 05:37:34 +08:00
|
|
|
int x;
|
|
|
|
int y;
|
1999-10-27 02:27:27 +08:00
|
|
|
GPattern *pattern;
|
1999-05-02 05:37:34 +08:00
|
|
|
} popup_timeout_args_t;
|
|
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
pattern_popup_timeout (gpointer data)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-05-02 05:37:34 +08:00
|
|
|
popup_timeout_args_t *args = data;
|
1999-10-27 02:27:27 +08:00
|
|
|
PatternSelect *psp = args->psp;
|
|
|
|
GPattern *pattern = args->pattern;
|
1999-05-02 05:37:34 +08:00
|
|
|
gint x, y;
|
1997-11-25 06:05:25 +08:00
|
|
|
gint x_org, y_org;
|
|
|
|
gint scr_w, scr_h;
|
|
|
|
gchar *src, *buf;
|
1997-12-18 12:19:11 +08:00
|
|
|
|
1999-05-02 05:37:34 +08:00
|
|
|
/* timeout has gone off so our tag is now invalid */
|
|
|
|
psp->popup_timeout_tag = 0;
|
|
|
|
|
1997-12-18 12:19:11 +08:00
|
|
|
/* make sure the popup exists and is not visible */
|
1997-11-25 06:05:25 +08:00
|
|
|
if (psp->pattern_popup == NULL)
|
|
|
|
{
|
|
|
|
GtkWidget *frame;
|
|
|
|
psp->pattern_popup = gtk_window_new (GTK_WINDOW_POPUP);
|
1999-05-02 05:37:34 +08:00
|
|
|
gtk_window_set_policy (GTK_WINDOW (psp->pattern_popup),
|
|
|
|
FALSE, FALSE, TRUE);
|
1997-11-25 06:05:25 +08:00
|
|
|
frame = gtk_frame_new (NULL);
|
|
|
|
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
|
|
|
|
gtk_container_add (GTK_CONTAINER (psp->pattern_popup), frame);
|
|
|
|
gtk_widget_show (frame);
|
|
|
|
psp->pattern_preview = gtk_preview_new (GTK_PREVIEW_COLOR);
|
|
|
|
gtk_container_add (GTK_CONTAINER (frame), psp->pattern_preview);
|
|
|
|
gtk_widget_show (psp->pattern_preview);
|
|
|
|
}
|
|
|
|
else
|
1997-12-18 12:19:11 +08:00
|
|
|
{
|
|
|
|
gtk_widget_hide (psp->pattern_popup);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* decide where to put the popup */
|
1997-11-25 06:05:25 +08:00
|
|
|
gdk_window_get_origin (psp->preview->window, &x_org, &y_org);
|
|
|
|
scr_w = gdk_screen_width ();
|
|
|
|
scr_h = gdk_screen_height ();
|
1999-05-02 05:37:34 +08:00
|
|
|
x = x_org + args->x - pattern->mask->width * 0.5;
|
|
|
|
y = y_org + args->y - pattern->mask->height * 0.5;
|
1997-11-25 06:05:25 +08:00
|
|
|
x = (x < 0) ? 0 : x;
|
|
|
|
y = (y < 0) ? 0 : y;
|
|
|
|
x = (x + pattern->mask->width > scr_w) ? scr_w - pattern->mask->width : x;
|
|
|
|
y = (y + pattern->mask->height > scr_h) ? scr_h - pattern->mask->height : y;
|
1999-05-02 05:37:34 +08:00
|
|
|
gtk_preview_size (GTK_PREVIEW (psp->pattern_preview),
|
|
|
|
pattern->mask->width, pattern->mask->height);
|
1997-11-25 06:05:25 +08:00
|
|
|
gtk_widget_popup (psp->pattern_popup, x, y);
|
1997-12-18 12:19:11 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* Draw the pattern */
|
|
|
|
buf = g_new (gchar, pattern->mask->width * 3);
|
1998-03-19 06:35:31 +08:00
|
|
|
src = (gchar *)temp_buf_data (pattern->mask);
|
1997-11-25 06:05:25 +08:00
|
|
|
for (y = 0; y < pattern->mask->height; y++)
|
|
|
|
{
|
|
|
|
if (pattern->mask->bytes == 1)
|
|
|
|
for (x = 0; x < pattern->mask->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 < pattern->mask->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];
|
|
|
|
}
|
1998-03-19 06:35:31 +08:00
|
|
|
gtk_preview_draw_row (GTK_PREVIEW (psp->pattern_preview), (guchar *)buf, 0, y, pattern->mask->width);
|
1997-11-25 06:05:25 +08:00
|
|
|
src += pattern->mask->width * pattern->mask->bytes;
|
|
|
|
}
|
1999-05-02 05:37:34 +08:00
|
|
|
g_free (buf);
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* Draw the pattern preview */
|
|
|
|
gtk_widget_draw (psp->pattern_preview, NULL);
|
1999-05-02 05:37:34 +08:00
|
|
|
|
|
|
|
return FALSE; /* don't repeat */
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-10-27 02:27:27 +08:00
|
|
|
pattern_popup_open (PatternSelect *psp,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
GPattern *pattern)
|
1999-05-02 05:37:34 +08:00
|
|
|
{
|
|
|
|
static popup_timeout_args_t popup_timeout_args;
|
|
|
|
|
|
|
|
/* if we've already got a timeout scheduled, then we complain */
|
|
|
|
g_return_if_fail (psp->popup_timeout_tag == 0);
|
|
|
|
|
|
|
|
popup_timeout_args.psp = psp;
|
|
|
|
popup_timeout_args.x = x;
|
|
|
|
popup_timeout_args.y = y;
|
|
|
|
popup_timeout_args.pattern = pattern;
|
|
|
|
psp->popup_timeout_tag = gtk_timeout_add (POPUP_DELAY_MS,
|
|
|
|
pattern_popup_timeout,
|
|
|
|
&popup_timeout_args);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
1997-12-18 12:19:11 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
static void
|
1999-10-27 02:27:27 +08:00
|
|
|
pattern_popup_close (PatternSelect *psp)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-05-02 05:37:34 +08:00
|
|
|
if (psp->popup_timeout_tag != 0)
|
|
|
|
gtk_timeout_remove (psp->popup_timeout_tag);
|
|
|
|
psp->popup_timeout_tag = 0;
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
if (psp->pattern_popup != NULL)
|
|
|
|
gtk_widget_hide (psp->pattern_popup);
|
|
|
|
}
|
1997-12-18 12:19:11 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
static void
|
1999-10-27 02:27:27 +08:00
|
|
|
display_setup (PatternSelect *psp)
|
|
|
|
{
|
|
|
|
guchar * buf;
|
|
|
|
gint i;
|
|
|
|
|
|
|
|
buf = g_new (guchar, 3 * psp->preview->allocation.width);
|
|
|
|
|
|
|
|
/* Set the buffer to white */
|
|
|
|
memset (buf, 255, psp->preview->allocation.width * 3);
|
|
|
|
|
|
|
|
/* Set the image buffer to white */
|
|
|
|
for (i = 0; i < psp->preview->allocation.height; i++)
|
|
|
|
gtk_preview_draw_row (GTK_PREVIEW (psp->preview), buf, 0, i,
|
|
|
|
psp->preview->allocation.width);
|
|
|
|
|
|
|
|
g_free (buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
display_pattern (PatternSelect *psp,
|
|
|
|
GPattern *pattern,
|
|
|
|
gint col,
|
|
|
|
gint row)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
TempBuf * pattern_buf;
|
1999-10-27 02:27:27 +08:00
|
|
|
guchar * src, *s;
|
|
|
|
guchar * buf, *b;
|
|
|
|
gint cell_width, cell_height;
|
|
|
|
gint width, height;
|
|
|
|
gint rowstride;
|
|
|
|
gint offset_x, offset_y;
|
|
|
|
gint yend;
|
|
|
|
gint ystart;
|
|
|
|
gint i, j;
|
|
|
|
|
|
|
|
buf = g_new (guchar, psp->cell_width * 3);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
pattern_buf = pattern->mask;
|
|
|
|
|
|
|
|
/* calculate the offset into the image */
|
|
|
|
cell_width = psp->cell_width - 2*MARGIN_WIDTH;
|
|
|
|
cell_height = psp->cell_height - 2*MARGIN_HEIGHT;
|
|
|
|
width = (pattern_buf->width > cell_width) ? cell_width :
|
|
|
|
pattern_buf->width;
|
|
|
|
height = (pattern_buf->height > cell_height) ? cell_height :
|
|
|
|
pattern_buf->height;
|
|
|
|
|
|
|
|
offset_x = col * psp->cell_width + ((cell_width - width) >> 1) + MARGIN_WIDTH;
|
|
|
|
offset_y = row * psp->cell_height + ((cell_height - height) >> 1)
|
|
|
|
- psp->scroll_offset + MARGIN_HEIGHT;
|
|
|
|
|
1999-04-23 22:47:50 +08:00
|
|
|
ystart = BOUNDS (offset_y, 0, psp->preview->allocation.height);
|
|
|
|
yend = BOUNDS (offset_y + height, 0, psp->preview->allocation.height);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* Get the pointer into the pattern mask data */
|
|
|
|
rowstride = pattern_buf->width * pattern_buf->bytes;
|
|
|
|
src = temp_buf_data (pattern_buf) + (ystart - offset_y) * rowstride;
|
|
|
|
|
|
|
|
for (i = ystart; i < yend; i++)
|
|
|
|
{
|
|
|
|
s = src;
|
|
|
|
b = buf;
|
|
|
|
|
|
|
|
if (pattern_buf->bytes == 1)
|
|
|
|
for (j = 0; j < width; j++)
|
|
|
|
{
|
|
|
|
*b++ = *s;
|
|
|
|
*b++ = *s;
|
|
|
|
*b++ = *s++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
for (j = 0; j < width; j++)
|
|
|
|
{
|
|
|
|
*b++ = *s++;
|
|
|
|
*b++ = *s++;
|
|
|
|
*b++ = *s++;
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_preview_draw_row (GTK_PREVIEW (psp->preview), buf, offset_x, i, width);
|
|
|
|
|
|
|
|
src += rowstride;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-10-27 02:27:27 +08:00
|
|
|
display_patterns (PatternSelect *psp)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1998-01-29 16:03:27 +08:00
|
|
|
GSList *list = pattern_list; /* the global pattern list */
|
1999-10-27 02:27:27 +08:00
|
|
|
gint row, col;
|
|
|
|
GPattern *pattern;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
if (list == NULL)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
gtk_widget_set_sensitive (psp->options_box, FALSE);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
1999-10-27 02:27:27 +08:00
|
|
|
{
|
|
|
|
gtk_widget_set_sensitive (psp->options_box, TRUE);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* setup the display area */
|
|
|
|
display_setup (psp);
|
|
|
|
|
|
|
|
row = col = 0;
|
1999-10-27 02:27:27 +08:00
|
|
|
for (; list; list = g_slist_next (list))
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
pattern = (GPattern *) list->data;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* Display the pattern */
|
|
|
|
display_pattern (psp, pattern, col, row);
|
|
|
|
|
|
|
|
/* increment the counts */
|
1998-10-02 06:09:01 +08:00
|
|
|
if (++col == psp->NUM_PATTERN_COLUMNS)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
row ++;
|
|
|
|
col = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-10-27 02:27:27 +08:00
|
|
|
pattern_select_show_selected (PatternSelect *psp,
|
|
|
|
gint row,
|
|
|
|
gint col)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
GdkRectangle area;
|
1999-10-27 02:27:27 +08:00
|
|
|
guchar * buf;
|
|
|
|
gint yend;
|
|
|
|
gint ystart;
|
|
|
|
gint offset_x, offset_y;
|
|
|
|
gint i;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
buf = g_new (guchar, 3 * psp->cell_width);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1998-10-02 06:09:01 +08:00
|
|
|
if (psp->old_col != col || psp->old_row != row)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
/* remove the old selection */
|
1998-10-02 06:09:01 +08:00
|
|
|
offset_x = psp->old_col * psp->cell_width;
|
|
|
|
offset_y = psp->old_row * psp->cell_height - psp->scroll_offset;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-04-23 22:47:50 +08:00
|
|
|
ystart = BOUNDS (offset_y , 0, psp->preview->allocation.height);
|
|
|
|
yend = BOUNDS (offset_y + psp->cell_height, 0, psp->preview->allocation.height);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* set the buf to white */
|
1999-10-27 02:27:27 +08:00
|
|
|
memset (buf, 255, 3 * psp->cell_width);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
for (i = ystart; i < yend; i++)
|
|
|
|
{
|
|
|
|
if (i == offset_y || i == (offset_y + psp->cell_height - 1))
|
1999-10-27 02:27:27 +08:00
|
|
|
gtk_preview_draw_row (GTK_PREVIEW (psp->preview), buf,
|
|
|
|
offset_x, i, psp->cell_width);
|
1997-11-25 06:05:25 +08:00
|
|
|
else
|
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
gtk_preview_draw_row (GTK_PREVIEW (psp->preview), buf,
|
|
|
|
offset_x, i, 1);
|
|
|
|
gtk_preview_draw_row (GTK_PREVIEW (psp->preview), buf,
|
|
|
|
offset_x + psp->cell_width - 1, i, 1);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
area.x = offset_x;
|
|
|
|
area.y = ystart;
|
|
|
|
area.width = psp->cell_width;
|
|
|
|
area.height = yend - ystart;
|
|
|
|
gtk_widget_draw (psp->preview, &area);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* make the new selection */
|
|
|
|
offset_x = col * psp->cell_width;
|
|
|
|
offset_y = row * psp->cell_height - psp->scroll_offset;
|
|
|
|
|
1999-04-23 22:47:50 +08:00
|
|
|
ystart = BOUNDS (offset_y , 0, psp->preview->allocation.height);
|
|
|
|
yend = BOUNDS (offset_y + psp->cell_height, 0, psp->preview->allocation.height);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* set the buf to black */
|
|
|
|
memset (buf, 0, psp->cell_width * 3);
|
|
|
|
|
|
|
|
for (i = ystart; i < yend; i++)
|
|
|
|
{
|
|
|
|
if (i == offset_y || i == (offset_y + psp->cell_height - 1))
|
1999-10-27 02:27:27 +08:00
|
|
|
gtk_preview_draw_row (GTK_PREVIEW (psp->preview), buf,
|
|
|
|
offset_x, i, psp->cell_width);
|
1997-11-25 06:05:25 +08:00
|
|
|
else
|
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
gtk_preview_draw_row (GTK_PREVIEW (psp->preview), buf,
|
|
|
|
offset_x, i, 1);
|
|
|
|
gtk_preview_draw_row (GTK_PREVIEW (psp->preview), buf,
|
|
|
|
offset_x + psp->cell_width - 1, i, 1);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
area.x = offset_x;
|
|
|
|
area.y = ystart;
|
|
|
|
area.width = psp->cell_width;
|
|
|
|
area.height = yend - ystart;
|
|
|
|
gtk_widget_draw (psp->preview, &area);
|
|
|
|
|
1998-10-02 06:09:01 +08:00
|
|
|
psp->old_row = row;
|
|
|
|
psp->old_col = col;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
g_free (buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-10-27 02:27:27 +08:00
|
|
|
update_active_pattern_field (PatternSelect *psp)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
GPattern *pattern;
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
gchar buf[32];
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
pattern = gimp_context_get_pattern (psp->context);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
if (!pattern)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Set pattern name */
|
1999-01-11 05:54:02 +08:00
|
|
|
gtk_label_set_text (GTK_LABEL (psp->pattern_name), pattern->name);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* Set pattern size */
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
g_snprintf (buf, sizeof (buf), "(%d X %d)",
|
|
|
|
pattern->mask->width, pattern->mask->height);
|
1999-01-11 05:54:02 +08:00
|
|
|
gtk_label_set_text (GTK_LABEL (psp->pattern_size), buf);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
static void
|
|
|
|
preview_calc_scrollbar (PatternSelect *psp)
|
|
|
|
{
|
|
|
|
gint num_rows;
|
|
|
|
gint page_size;
|
|
|
|
gint max;
|
|
|
|
|
|
|
|
psp->scroll_offset = 0;
|
|
|
|
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;
|
|
|
|
|
|
|
|
psp->sbar_data->value = psp->scroll_offset;
|
|
|
|
psp->sbar_data->upper = max;
|
|
|
|
psp->sbar_data->page_size = (page_size < max) ? page_size : max;
|
|
|
|
psp->sbar_data->page_increment = (page_size >> 1);
|
|
|
|
psp->sbar_data->step_increment = psp->cell_width;
|
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
gtk_signal_emit_by_name (GTK_OBJECT (psp->sbar_data), "changed");
|
1999-10-27 02:27:27 +08:00
|
|
|
gtk_signal_emit_by_name (GTK_OBJECT (psp->sbar_data), "value_changed");
|
|
|
|
}
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
static gint
|
1999-10-27 02:27:27 +08:00
|
|
|
pattern_select_resize (GtkWidget *widget,
|
|
|
|
GdkEvent *event,
|
|
|
|
PatternSelect *psp)
|
1999-04-23 22:47:50 +08:00
|
|
|
{
|
1999-04-29 16:50:22 +08:00
|
|
|
/* calculate the best-fit approximation... */
|
1997-11-25 06:05:25 +08:00
|
|
|
gint wid;
|
|
|
|
gint now;
|
1999-04-29 16:50:22 +08:00
|
|
|
gint cell_size;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-04-23 22:47:50 +08:00
|
|
|
wid = widget->allocation.width;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
for (now = cell_size = MIN_CELL_SIZE;
|
|
|
|
now < MAX_CELL_SIZE; ++now)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-04-29 16:50:22 +08:00
|
|
|
if ((wid % now) < (wid % cell_size)) cell_size = now;
|
|
|
|
if ((wid % cell_size) == 0)
|
1997-11-25 06:05:25 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
1999-04-23 22:47:50 +08:00
|
|
|
psp->NUM_PATTERN_COLUMNS =
|
1999-04-29 16:50:22 +08:00
|
|
|
(gint) (wid / cell_size);
|
1999-04-23 22:47:50 +08:00
|
|
|
psp->NUM_PATTERN_ROWS =
|
1999-04-29 16:50:22 +08:00
|
|
|
(gint) ((num_patterns + psp->NUM_PATTERN_COLUMNS - 1) /
|
1999-04-23 22:47:50 +08:00
|
|
|
psp->NUM_PATTERN_COLUMNS);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
psp->cell_width = cell_size;
|
1999-04-29 16:50:22 +08:00
|
|
|
psp->cell_height = cell_size;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* recalculate scrollbar extents */
|
|
|
|
preview_calc_scrollbar (psp);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
1999-10-27 02:27:27 +08:00
|
|
|
pattern_select_events (GtkWidget *widget,
|
|
|
|
GdkEvent *event,
|
|
|
|
PatternSelect *psp)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
GdkEventButton *bevent;
|
1999-10-27 02:27:27 +08:00
|
|
|
GPattern *pattern;
|
1997-11-25 06:05:25 +08:00
|
|
|
int row, col, index;
|
|
|
|
|
|
|
|
switch (event->type)
|
|
|
|
{
|
|
|
|
case GDK_BUTTON_PRESS:
|
|
|
|
bevent = (GdkEventButton *) event;
|
|
|
|
|
|
|
|
if (bevent->button == 1)
|
|
|
|
{
|
|
|
|
col = bevent->x / psp->cell_width;
|
|
|
|
row = (bevent->y + psp->scroll_offset) / psp->cell_height;
|
1998-10-02 06:09:01 +08:00
|
|
|
index = row * psp->NUM_PATTERN_COLUMNS + col;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* Get the pattern and display the popup pattern preview */
|
1999-10-27 02:27:27 +08:00
|
|
|
if ((pattern = pattern_list_get_pattern_by_index (pattern_list,
|
|
|
|
index)))
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
gdk_pointer_grab (psp->preview->window, FALSE,
|
|
|
|
(GDK_POINTER_MOTION_HINT_MASK |
|
|
|
|
GDK_BUTTON1_MOTION_MASK |
|
|
|
|
GDK_BUTTON_RELEASE_MASK),
|
|
|
|
NULL, NULL, bevent->time);
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
/* Make this pattern the active pattern */
|
|
|
|
gimp_context_set_pattern (psp->context, pattern);
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* Show the pattern popup window if the pattern is too large */
|
1999-10-27 02:27:27 +08:00
|
|
|
if (pattern->mask->width > psp->cell_width ||
|
1997-11-25 06:05:25 +08:00
|
|
|
pattern->mask->height > psp->cell_height)
|
1999-10-27 02:27:27 +08:00
|
|
|
{
|
|
|
|
pattern_popup_open (psp, bevent->x, bevent->y, pattern);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
1999-07-25 00:27:47 +08:00
|
|
|
|
|
|
|
/* wheelmouse support */
|
|
|
|
else if (bevent->button == 4)
|
|
|
|
{
|
|
|
|
GtkAdjustment *adj = psp->sbar_data;
|
|
|
|
gfloat new_value = adj->value - adj->page_increment / 2;
|
|
|
|
new_value =
|
|
|
|
CLAMP (new_value, adj->lower, adj->upper - adj->page_size);
|
|
|
|
gtk_adjustment_set_value (adj, new_value);
|
|
|
|
}
|
|
|
|
else if (bevent->button == 5)
|
|
|
|
{
|
|
|
|
GtkAdjustment *adj = psp->sbar_data;
|
|
|
|
gfloat new_value = adj->value + adj->page_increment / 2;
|
|
|
|
new_value =
|
|
|
|
CLAMP (new_value, adj->lower, adj->upper - adj->page_size);
|
|
|
|
gtk_adjustment_set_value (adj, new_value);
|
|
|
|
}
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case GDK_BUTTON_RELEASE:
|
|
|
|
bevent = (GdkEventButton *) event;
|
|
|
|
|
|
|
|
if (bevent->button == 1)
|
|
|
|
{
|
|
|
|
/* Ungrab the pointer */
|
|
|
|
gdk_pointer_ungrab (bevent->time);
|
|
|
|
|
|
|
|
/* Close the brush popup window */
|
|
|
|
pattern_popup_close (psp);
|
1998-10-02 06:09:01 +08:00
|
|
|
|
|
|
|
/* Call any callbacks registered */
|
1999-10-28 23:05:49 +08:00
|
|
|
pattern_change_callbacks (psp, FALSE);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
pattern_select_scroll_update (GtkAdjustment *adjustment,
|
|
|
|
gpointer data)
|
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
PatternSelect *psp;
|
|
|
|
GPattern *active;
|
|
|
|
gint row, col, index;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
psp = (PatternSelect *) data;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
if (psp)
|
|
|
|
{
|
|
|
|
psp->scroll_offset = adjustment->value;
|
1999-10-27 02:27:27 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
display_patterns (psp);
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
active = gimp_context_get_pattern (psp->context);
|
1998-10-02 06:09:01 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
if (active)
|
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
index = active->index;
|
|
|
|
row = index / psp->NUM_PATTERN_COLUMNS;
|
|
|
|
col = index - row * psp->NUM_PATTERN_COLUMNS;
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
pattern_select_show_selected (psp, row, col);
|
|
|
|
}
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
gtk_widget_draw (psp->preview, NULL);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
1998-10-02 06:09:01 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
static void
|
|
|
|
pattern_select_close_callback (GtkWidget *widget,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
PatternSelect *psp;
|
1998-10-02 06:09:01 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
psp = (PatternSelect *) data;
|
1998-10-02 06:09:01 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
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 */
|
1999-10-28 23:05:49 +08:00
|
|
|
pattern_change_callbacks (psp, TRUE);
|
1999-10-27 02:27:27 +08:00
|
|
|
gtk_widget_destroy (psp->shell);
|
|
|
|
pattern_select_free (psp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
pattern_select_refresh_callback (GtkWidget *widget,
|
|
|
|
gpointer data)
|
1998-10-02 06:09:01 +08:00
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
PatternSelect *psp;
|
1998-10-02 06:09:01 +08:00
|
|
|
GSList *list;
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
/* re-init the pattern list */
|
|
|
|
patterns_init (FALSE);
|
1998-10-02 06:09:01 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
for (list = pattern_active_dialogs; list; list = g_slist_next (list))
|
1998-10-02 06:09:01 +08:00
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
psp = (PatternSelect *) list->data;
|
1999-09-28 01:58:10 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
/* recalculate scrollbar extents */
|
|
|
|
preview_calc_scrollbar (psp);
|
1998-10-02 06:09:01 +08:00
|
|
|
}
|
|
|
|
}
|