gimp/app/gui/pattern-select.c

1201 lines
31 KiB
C
Raw Normal View History

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
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1997-11-25 06:05:25 +08:00
*/
app/Makefile.am app/channel_pvt.h app/drawable_pvt.h app/gdisplayF.h 2000-12-29 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/channel_pvt.h * app/drawable_pvt.h * app/gdisplayF.h * app/gimpdrawableP.h * app/gimpimageP.h * app/layer_pvt.h * app/toolsF.h: removed these files. * app/apptypes.h * tools/pdbgen/enums.pl: added tons of opaque typedefs and enums. * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/channel.pdb * tools/pdbgen/pdb/color.pdb * tools/pdbgen/pdb/convert.pdb * tools/pdbgen/pdb/display.pdb * tools/pdbgen/pdb/drawable.pdb * tools/pdbgen/pdb/fileops.pdb * tools/pdbgen/pdb/gradient_select.pdb * tools/pdbgen/pdb/gradients.pdb * tools/pdbgen/pdb/help.pdb * tools/pdbgen/pdb/image.pdb * tools/pdbgen/pdb/layer.pdb * tools/pdbgen/pdb/pattern_select.pdb * tools/pdbgen/pdb/patterns.pdb * tools/pdbgen/pdb/selection.pdb * tools/pdbgen/pdb/tools.pdb * app/*: chainsaw #include cleanup: - Never (never!!) include stuff in header files except where we need access to structures' contents (like derived objects). - Added prototypes and proper formating in many files. - The #include order in *all* *.c files is as follows: #include "config.h" #include <system stuff> #include <gtk/gtk.h> #include "apptypes.h" #include "gimp stuff" #include "libgimp stuff" #include "libgimp/gimpintl.h" By following this scheme we can easily see a file's dependencies from it's #include's and can grep for the inclusion to find out where a file is used. * tools/pdbgen/app.pl: changed to follow the include scheme above. * libgimp/Makefile.am * libgimp/gimpuitypes.h: new file, included from libgimp/gimpui.h and from app/apptypes.h. * libgimp/gimpcolorbutton.[ch] * libgimp/gimpdialog.[ch] * libgimp/gimphelpui.[ch] * libgimp/gimpparasite.[ch] * libgimp/gimppatheditor.[ch] * libgimp/gimpprotocol.c * libgimp/gimpquerybox.[ch] * libgimp/gimpsizeentry.[ch] * libgimp/gimptypes.h * libgimp/gimpui.h * libgimp/gimpunit.h * libgimp/gimpunitmenu.[ch] * libgimp/gimpwidgets.[ch]: changed accordingly. * plug-ins/FractalExplorer/Dialogs.c * plug-ins/gdyntext/message_window.c * plug-ins/imagemap/imap_default_dialog.c * plug-ins/imagemap/imap_file.c: these files used to include "libgimp/gimpui.h" without including "libgimp/gimp.h". This is no longer possible because the libgimpui headers don't inlcude "libgimp/gimpunit.h" any more.
2000-12-29 23:22:01 +08:00
#include "config.h"
1997-11-25 06:05:25 +08:00
#include <string.h>
1999-10-27 02:27:27 +08:00
#include <gtk/gtk.h>
Makefile.am configure.in added the new library below. 2001-01-24 Michael Natterer <mitch@gimp.org> * Makefile.am * configure.in * gimptool.in: added the new library below. * libgimpwidgets/Makefile.am * libgimpwidgets/gimpchainbutton.[ch] * libgimpwidgets/gimpcolorarea.[ch] * libgimpwidgets/gimpcolorbutton.[ch] * libgimpwidgets/gimpdialog.[ch] * libgimpwidgets/gimpfileselection.[ch] * libgimpwidgets/gimphelpui.[ch] * libgimpwidgets/gimppatheditor.[ch] * libgimpwidgets/gimppixmap.[ch] * libgimpwidgets/gimpquerybox.[ch] * libgimpwidgets/gimpsizeentry.[ch] * libgimpwidgets/gimpunitmenu.[ch] * libgimpwidgets/gimpwidgets.[ch] * libgimpwidgets/gimpwidgets.def * libgimpwidgets/gimpwidgetstypes.h: new shared library. Currently there are some ugly dependencies into libgimp. These will be removed and go to a "libgimpglue" library which will be a library for functions which share a common interface between plug-ins and the app but have different implementations. Include "libgimp/gimpunit.h" from "libgimpwidgets/gimpwidgetstypes.h" to simulate this upcoming separation. * libgimp/Makefile.am * libgimp/gimpchainbutton.[ch] * libgimp/gimpcolorarea.[ch] * libgimp/gimpcolorbutton.[ch] * libgimp/gimpdialog.[ch] * libgimp/gimpfileselection.[ch] * libgimp/gimphelpui.[ch] * libgimp/gimppatheditor.[ch] * libgimp/gimppixmap.[ch] * libgimp/gimpquerybox.[ch] * libgimp/gimpsizeentry.[ch] * libgimp/gimpunitmenu.[ch] * libgimp/gimpwidgets.[ch]: removed from here. * libgimp/gimpui.h * libgimp/gimpuitypes.h * libgimp/makefile.mingw.in * libgimp/makefile.msc: changed accordingly. * app/[all ui files] * app/pdb/palette_cmds.c * app/pdb/tools_cmds.c * tools/pdbgen/pdb/palette.pdb * tools/pdbgen/pdb/tools.pdb: #include "libgimpwidgets/gimpwidgets.h" and removed useless includes. * app/apptypes.h: #include "libgimpwidgets/gimpwidgetstypes.h" * app/Makefile.am * plug-ins/[all makefiles which link against libgimpui]: link against libgimpwidgets.la * po-libgimp/POTFILES.in: changed file locations.
2001-01-25 06:36:18 +08:00
#include "libgimpwidgets/gimpwidgets.h"
#include "apptypes.h"
1997-11-25 06:05:25 +08:00
#include "appenv.h"
took gimpcontextpreview.[ch] out of the build but still left the sources 2001-02-12 Michael Natterer <mitch@gimp.org> * app/Makefile.am: took gimpcontextpreview.[ch] out of the build but still left the sources there as reference. * app/app_procs.c: initialize the render stuff before creating the toolbox (needed for the previews). * app/devices.c * app/indicator_area.c: use GimpPreviews instead of GimpContextPreviews. * app/context_manager.[ch]: create the global data lists here because they now must exist before any context is created. * app/brushes.[ch] * app/gradients.[ch] * app/palettes.[ch] * app/patterns.[ch]: removed them here. * app/gimpcontainer.[ch]: added a "freeze_count" and emit the "freeze" and "thaw" signals accordingly. * app/gimpcontext.[ch]: greatly simplified the way how the contexts connect to the data lists (simply keep them connected all the time). Also removed all those ugly explicit update functions because "thaw" callbacks do this job now. * app/gimpdata.c: a GimpData object now becomes dirty on "name_changed"; "dirty" now triggers "invalidate_preview" because the context does not dispatch these signals any more soon. * app/brush_select.c * app/convert.c * app/gimpdnd.c * app/gradient_editor.c * app/gradient_select.c * app/pattern_select.c * app/gradient_editor.c * app/gradient_select.c * app/gradients.[ch] * app/pdb/brush_select_cmds.c * app/pdb/brushes_cmds.c * app/pdb/convert_cmds.c * app/pdb/gradient_select_cmds.c * app/pdb/gradients_cmds.c * app/pdb/pattern_select_cmds.c * app/pdb/patterns_cmds.c * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/convert.pdb * tools/pdbgen/pdb/gradient_select.pdb * tools/pdbgen/pdb/gradients.pdb * tools/pdbgen/pdb/pattern_select.pdb * tools/pdbgen/pdb/patterns.pdb: changed accordingly.
2001-02-12 11:27:28 +08:00
#include "context_manager.h"
1999-10-27 02:27:27 +08:00
#include "dialog_handler.h"
#include "gimpcontainer.h"
1999-10-27 02:27:27 +08:00
#include "gimpcontext.h"
1999-10-28 23:05:49 +08:00
#include "gimpdnd.h"
#include "gimplist.h"
#include "gimppattern.h"
1997-11-25 06:05:25 +08:00
#include "patterns.h"
#include "pattern_select.h"
#include "session.h"
app/Makefile.am app/channel_pvt.h app/drawable_pvt.h app/gdisplayF.h 2000-12-29 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/channel_pvt.h * app/drawable_pvt.h * app/gdisplayF.h * app/gimpdrawableP.h * app/gimpimageP.h * app/layer_pvt.h * app/toolsF.h: removed these files. * app/apptypes.h * tools/pdbgen/enums.pl: added tons of opaque typedefs and enums. * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/channel.pdb * tools/pdbgen/pdb/color.pdb * tools/pdbgen/pdb/convert.pdb * tools/pdbgen/pdb/display.pdb * tools/pdbgen/pdb/drawable.pdb * tools/pdbgen/pdb/fileops.pdb * tools/pdbgen/pdb/gradient_select.pdb * tools/pdbgen/pdb/gradients.pdb * tools/pdbgen/pdb/help.pdb * tools/pdbgen/pdb/image.pdb * tools/pdbgen/pdb/layer.pdb * tools/pdbgen/pdb/pattern_select.pdb * tools/pdbgen/pdb/patterns.pdb * tools/pdbgen/pdb/selection.pdb * tools/pdbgen/pdb/tools.pdb * app/*: chainsaw #include cleanup: - Never (never!!) include stuff in header files except where we need access to structures' contents (like derived objects). - Added prototypes and proper formating in many files. - The #include order in *all* *.c files is as follows: #include "config.h" #include <system stuff> #include <gtk/gtk.h> #include "apptypes.h" #include "gimp stuff" #include "libgimp stuff" #include "libgimp/gimpintl.h" By following this scheme we can easily see a file's dependencies from it's #include's and can grep for the inclusion to find out where a file is used. * tools/pdbgen/app.pl: changed to follow the include scheme above. * libgimp/Makefile.am * libgimp/gimpuitypes.h: new file, included from libgimp/gimpui.h and from app/apptypes.h. * libgimp/gimpcolorbutton.[ch] * libgimp/gimpdialog.[ch] * libgimp/gimphelpui.[ch] * libgimp/gimpparasite.[ch] * libgimp/gimppatheditor.[ch] * libgimp/gimpprotocol.c * libgimp/gimpquerybox.[ch] * libgimp/gimpsizeentry.[ch] * libgimp/gimptypes.h * libgimp/gimpui.h * libgimp/gimpunit.h * libgimp/gimpunitmenu.[ch] * libgimp/gimpwidgets.[ch]: changed accordingly. * plug-ins/FractalExplorer/Dialogs.c * plug-ins/gdyntext/message_window.c * plug-ins/imagemap/imap_default_dialog.c * plug-ins/imagemap/imap_file.c: these files used to include "libgimp/gimpui.h" without including "libgimp/gimp.h". This is no longer possible because the libgimpui headers don't inlcude "libgimp/gimpunit.h" any more.
2000-12-29 23:22:01 +08:00
#include "temp_buf.h"
1997-11-25 06:05:25 +08:00
#include "pdb/procedural_db.h"
#include "libgimp/gimpintl.h"
1997-11-25 06:05:25 +08:00
app/Makefile.am app/channel_pvt.h app/drawable_pvt.h app/gdisplayF.h 2000-12-29 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/channel_pvt.h * app/drawable_pvt.h * app/gdisplayF.h * app/gimpdrawableP.h * app/gimpimageP.h * app/layer_pvt.h * app/toolsF.h: removed these files. * app/apptypes.h * tools/pdbgen/enums.pl: added tons of opaque typedefs and enums. * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/channel.pdb * tools/pdbgen/pdb/color.pdb * tools/pdbgen/pdb/convert.pdb * tools/pdbgen/pdb/display.pdb * tools/pdbgen/pdb/drawable.pdb * tools/pdbgen/pdb/fileops.pdb * tools/pdbgen/pdb/gradient_select.pdb * tools/pdbgen/pdb/gradients.pdb * tools/pdbgen/pdb/help.pdb * tools/pdbgen/pdb/image.pdb * tools/pdbgen/pdb/layer.pdb * tools/pdbgen/pdb/pattern_select.pdb * tools/pdbgen/pdb/patterns.pdb * tools/pdbgen/pdb/selection.pdb * tools/pdbgen/pdb/tools.pdb * app/*: chainsaw #include cleanup: - Never (never!!) include stuff in header files except where we need access to structures' contents (like derived objects). - Added prototypes and proper formating in many files. - The #include order in *all* *.c files is as follows: #include "config.h" #include <system stuff> #include <gtk/gtk.h> #include "apptypes.h" #include "gimp stuff" #include "libgimp stuff" #include "libgimp/gimpintl.h" By following this scheme we can easily see a file's dependencies from it's #include's and can grep for the inclusion to find out where a file is used. * tools/pdbgen/app.pl: changed to follow the include scheme above. * libgimp/Makefile.am * libgimp/gimpuitypes.h: new file, included from libgimp/gimpui.h and from app/apptypes.h. * libgimp/gimpcolorbutton.[ch] * libgimp/gimpdialog.[ch] * libgimp/gimphelpui.[ch] * libgimp/gimpparasite.[ch] * libgimp/gimppatheditor.[ch] * libgimp/gimpprotocol.c * libgimp/gimpquerybox.[ch] * libgimp/gimpsizeentry.[ch] * libgimp/gimptypes.h * libgimp/gimpui.h * libgimp/gimpunit.h * libgimp/gimpunitmenu.[ch] * libgimp/gimpwidgets.[ch]: changed accordingly. * plug-ins/FractalExplorer/Dialogs.c * plug-ins/gdyntext/message_window.c * plug-ins/imagemap/imap_default_dialog.c * plug-ins/imagemap/imap_file.c: these files used to include "libgimp/gimpui.h" without including "libgimp/gimp.h". This is no longer possible because the libgimpui headers don't inlcude "libgimp/gimpunit.h" any more.
2000-12-29 23:22:01 +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
/* how long to wait after mouse-down before showing pattern popup */
#define POPUP_DELAY_MS 150
#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 GimpPattern * pattern_select_drag_pattern(GtkWidget *widget,
gpointer data);
1999-10-28 23:05:49 +08:00
static void pattern_select_drop_pattern (GtkWidget *widget,
GimpPattern *pattern,
1999-10-28 23:05:49 +08:00
gpointer data);
1999-10-27 02:27:27 +08:00
static void pattern_select_pattern_changed (GimpContext *context,
GimpPattern *pattern,
1999-10-27 02:27:27 +08:00
PatternSelect *psp);
static void pattern_select_select (PatternSelect *psp,
GimpPattern *pattern);
static void pattern_select_pattern_dirty_callback (GimpPattern *brush,
PatternSelect *psp);
static void pattern_added_callback (GimpContainer *container,
GimpPattern *pattern,
PatternSelect *psp);
static void pattern_removed_callback (GimpContainer *container,
GimpPattern *pattern,
PatternSelect *psp);
1999-10-27 02:27:27 +08:00
static gboolean pattern_popup_timeout (gpointer data);
static void pattern_popup_open (PatternSelect *psp,
gint ,
gint ,
GimpPattern *pattern);
static void pattern_popup_close (PatternSelect *psp);
static void display_setup (PatternSelect *psp);
static void display_pattern (PatternSelect *psp,
GimpPattern *pattern,
gint ,
gint );
static void display_patterns (PatternSelect *psp);
static void pattern_select_show_selected (PatternSelect *psp,
gint ,
gint );
static void update_active_pattern_field (PatternSelect *psp);
static void preview_calc_scrollbar (PatternSelect *psp);
static gint pattern_select_resize (GtkWidget *widget,
GdkEvent *event,
PatternSelect *psp);
static gint pattern_select_events (GtkWidget *widget,
GdkEvent *event,
PatternSelect *psp);
1999-10-27 02:27:27 +08:00
static void pattern_select_scroll_update (GtkAdjustment *adjustment,
gpointer data);
1997-11-25 06:05:25 +08:00
static void pattern_select_close_callback (GtkWidget *widget,
gpointer data);
static void pattern_select_refresh_callback (GtkWidget *widget,
gpointer data);
1999-10-27 02:27:27 +08:00
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
/* local variables */
1997-11-25 06:05:25 +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;
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 (void)
1999-10-27 02:27:27 +08:00
{
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;
}
}
/* If title == NULL then it is the main pattern dialog */
1999-10-27 02:27:27 +08:00
PatternSelect *
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;
GtkWidget *frame;
1997-11-25 06:05:25 +08:00
GtkWidget *sbar;
GtkWidget *label_box;
GimpPattern *active = NULL;
1999-10-27 02:27:27 +08:00
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->dnd_pattern = NULL;
1999-10-27 02:27:27 +08:00
psp->pattern_popup = NULL;
psp->popup_timeout_tag = 0;
psp->old_col = 0;
psp->old_row = 0;
psp->NUM_PATTERN_COLUMNS = STD_PATTERN_COLUMNS;
psp->NUM_PATTERN_ROWS = STD_PATTERN_COLUMNS;
psp->redraw = TRUE;
psp->freeze = FALSE;
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",
title ? GTK_WIN_POS_MOUSE : GTK_WIN_POS_NONE,
1999-10-27 02:27:27 +08:00
FALSE, TRUE, FALSE,
app/Makefile.am app/gimphelp.[ch] new files 1999-09-27 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/gimphelp.[ch] * app/gimpui.[ch]: new files * app/interface.[ch] * app/preferences_dialog.[ch] The GIMP Help System part 1: Press "F1" in any dialog to pop up the help page for this dialog. Moved the widget constructors from preferences_dialog.[ch] and the query boxes from interface.[ch] to gimpui.[ch]. The dialog constructors take a help_func and a help_data parameter and install the "F1" accelerator which emits the new "help" signal. The "help" signal callback calls help_func(help_data) which finally has to call gimp_help() which in turn invokes the help browser. Still have to find a proper way to (1) prevent "F1" being assigned to some menu item and (2) to catch "F1" while browsing the menu trees in order to pop up the help for the selected item. * app/menus.c: a <Toolbox>/File/Help... menu item. * app/commands.[ch]: a command callback for the "Help..." menu item. * app/gimprc.[ch]: new boolean gimprc variable "use_help". * app/info_dialog.[ch]: pass a help function and data to the info dialog constructor. * app/tools.[ch]: store the tools help page names in the tool info structure. Export a special tools_help_func() which shows the help page for the active tool. * app/[all files calling a dialog constructor]: pass the dialog's help page to the constructor. Most dialogs are now created by gimp_dialog_new() which also sets up the action_area and the WM delete event callback, so I removed the resp. code from these files. Fixed some minor bugs and did some other stuff but didn't change any logic except dialog creation. * plug-ins/helpbrowser/helpbrowser.c: don't try to call a running help browser and don't install any menu path (all done in app/gimphelp.[ch] now).
1999-09-28 01:58:10 +08:00
1999-10-27 02:27:27 +08:00
_("Refresh"), pattern_select_refresh_callback,
psp, NULL, NULL, FALSE, FALSE,
1999-10-27 02:27:27 +08:00
_("Close"), pattern_select_close_callback,
psp, NULL, NULL, TRUE, TRUE,
app/Makefile.am app/gimphelp.[ch] new files 1999-09-27 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/gimphelp.[ch] * app/gimpui.[ch]: new files * app/interface.[ch] * app/preferences_dialog.[ch] The GIMP Help System part 1: Press "F1" in any dialog to pop up the help page for this dialog. Moved the widget constructors from preferences_dialog.[ch] and the query boxes from interface.[ch] to gimpui.[ch]. The dialog constructors take a help_func and a help_data parameter and install the "F1" accelerator which emits the new "help" signal. The "help" signal callback calls help_func(help_data) which finally has to call gimp_help() which in turn invokes the help browser. Still have to find a proper way to (1) prevent "F1" being assigned to some menu item and (2) to catch "F1" while browsing the menu trees in order to pop up the help for the selected item. * app/menus.c: a <Toolbox>/File/Help... menu item. * app/commands.[ch]: a command callback for the "Help..." menu item. * app/gimprc.[ch]: new boolean gimprc variable "use_help". * app/info_dialog.[ch]: pass a help function and data to the info dialog constructor. * app/tools.[ch]: store the tools help page names in the tool info structure. Export a special tools_help_func() which shows the help page for the active tool. * app/[all files calling a dialog constructor]: pass the dialog's help page to the constructor. Most dialogs are now created by gimp_dialog_new() which also sets up the action_area and the WM delete event callback, so I removed the resp. code from these files. Fixed some minor bugs and did some other stuff but didn't change any logic except dialog creation. * plug-ins/helpbrowser/helpbrowser.c: don't try to call a running help browser and don't install any menu path (all done in app/gimphelp.[ch] now).
1999-09-28 01:58:10 +08:00
1999-10-27 02:27:27 +08:00
NULL);
app/Makefile.am app/gimphelp.[ch] new files 1999-09-27 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/gimphelp.[ch] * app/gimpui.[ch]: new files * app/interface.[ch] * app/preferences_dialog.[ch] The GIMP Help System part 1: Press "F1" in any dialog to pop up the help page for this dialog. Moved the widget constructors from preferences_dialog.[ch] and the query boxes from interface.[ch] to gimpui.[ch]. The dialog constructors take a help_func and a help_data parameter and install the "F1" accelerator which emits the new "help" signal. The "help" signal callback calls help_func(help_data) which finally has to call gimp_help() which in turn invokes the help browser. Still have to find a proper way to (1) prevent "F1" being assigned to some menu item and (2) to catch "F1" while browsing the menu trees in order to pop up the help for the selected item. * app/menus.c: a <Toolbox>/File/Help... menu item. * app/commands.[ch]: a command callback for the "Help..." menu item. * app/gimprc.[ch]: new boolean gimprc variable "use_help". * app/info_dialog.[ch]: pass a help function and data to the info dialog constructor. * app/tools.[ch]: store the tools help page names in the tool info structure. Export a special tools_help_func() which shows the help page for the active tool. * app/[all files calling a dialog constructor]: pass the dialog's help page to the constructor. Most dialogs are now created by gimp_dialog_new() which also sets up the action_area and the WM delete event callback, so I removed the resp. code from these files. Fixed some minor bugs and did some other stuff but didn't change any logic except dialog creation. * plug-ins/helpbrowser/helpbrowser.c: don't try to call a running help browser and don't install any menu path (all done in app/gimphelp.[ch] now).
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);
}
app/Makefile.am app/gimphelp.[ch] new files 1999-09-27 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/gimphelp.[ch] * app/gimpui.[ch]: new files * app/interface.[ch] * app/preferences_dialog.[ch] The GIMP Help System part 1: Press "F1" in any dialog to pop up the help page for this dialog. Moved the widget constructors from preferences_dialog.[ch] and the query boxes from interface.[ch] to gimpui.[ch]. The dialog constructors take a help_func and a help_data parameter and install the "F1" accelerator which emits the new "help" signal. The "help" signal callback calls help_func(help_data) which finally has to call gimp_help() which in turn invokes the help browser. Still have to find a proper way to (1) prevent "F1" being assigned to some menu item and (2) to catch "F1" while browsing the menu trees in order to pop up the help for the selected item. * app/menus.c: a <Toolbox>/File/Help... menu item. * app/commands.[ch]: a command callback for the "Help..." menu item. * app/gimprc.[ch]: new boolean gimprc variable "use_help". * app/info_dialog.[ch]: pass a help function and data to the info dialog constructor. * app/tools.[ch]: store the tools help page names in the tool info structure. Export a special tools_help_func() which shows the help page for the active tool. * app/[all files calling a dialog constructor]: pass the dialog's help page to the constructor. Most dialogs are now created by gimp_dialog_new() which also sets up the action_area and the WM delete event callback, so I removed the resp. code from these files. Fixed some minor bugs and did some other stuff but didn't change any logic except dialog creation. * plug-ins/helpbrowser/helpbrowser.c: don't try to call a running help browser and don't install any menu path (all done in app/gimphelp.[ch] now).
1999-09-28 01:58:10 +08:00
else
{
1999-10-28 23:05:49 +08:00
psp->context = gimp_context_get_user ();
app/Makefile.am app/gimphelp.[ch] new files 1999-09-27 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/gimphelp.[ch] * app/gimpui.[ch]: new files * app/interface.[ch] * app/preferences_dialog.[ch] The GIMP Help System part 1: Press "F1" in any dialog to pop up the help page for this dialog. Moved the widget constructors from preferences_dialog.[ch] and the query boxes from interface.[ch] to gimpui.[ch]. The dialog constructors take a help_func and a help_data parameter and install the "F1" accelerator which emits the new "help" signal. The "help" signal callback calls help_func(help_data) which finally has to call gimp_help() which in turn invokes the help browser. Still have to find a proper way to (1) prevent "F1" being assigned to some menu item and (2) to catch "F1" while browsing the menu trees in order to pop up the help for the selected item. * app/menus.c: a <Toolbox>/File/Help... menu item. * app/commands.[ch]: a command callback for the "Help..." menu item. * app/gimprc.[ch]: new boolean gimprc variable "use_help". * app/info_dialog.[ch]: pass a help function and data to the info dialog constructor. * app/tools.[ch]: store the tools help page names in the tool info structure. Export a special tools_help_func() which shows the help page for the active tool. * app/[all files calling a dialog constructor]: pass the dialog's help page to the constructor. Most dialogs are now created by gimp_dialog_new() which also sets up the action_area and the WM delete event callback, so I removed the resp. code from these files. Fixed some minor bugs and did some other stuff but didn't change any logic except dialog creation. * plug-ins/helpbrowser/helpbrowser.c: don't try to call a running help browser and don't install any menu path (all done in app/gimphelp.[ch] now).
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 = (GimpPattern *)
gimp_container_get_child_by_name (global_pattern_list,
initial_pattern);
1999-10-27 02:27:27 +08:00
}
else
{
active = gimp_context_get_pattern (gimp_context_get_user ());
app/Makefile.am app/gimphelp.[ch] new files 1999-09-27 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/gimphelp.[ch] * app/gimpui.[ch]: new files * app/interface.[ch] * app/preferences_dialog.[ch] The GIMP Help System part 1: Press "F1" in any dialog to pop up the help page for this dialog. Moved the widget constructors from preferences_dialog.[ch] and the query boxes from interface.[ch] to gimpui.[ch]. The dialog constructors take a help_func and a help_data parameter and install the "F1" accelerator which emits the new "help" signal. The "help" signal callback calls help_func(help_data) which finally has to call gimp_help() which in turn invokes the help browser. Still have to find a proper way to (1) prevent "F1" being assigned to some menu item and (2) to catch "F1" while browsing the menu trees in order to pop up the help for the selected item. * app/menus.c: a <Toolbox>/File/Help... menu item. * app/commands.[ch]: a command callback for the "Help..." menu item. * app/gimprc.[ch]: new boolean gimprc variable "use_help". * app/info_dialog.[ch]: pass a help function and data to the info dialog constructor. * app/tools.[ch]: store the tools help page names in the tool info structure. Export a special tools_help_func() which shows the help page for the active tool. * app/[all files calling a dialog constructor]: pass the dialog's help page to the constructor. Most dialogs are now created by gimp_dialog_new() which also sets up the action_area and the WM delete event callback, so I removed the resp. code from these files. Fixed some minor bugs and did some other stuff but didn't change any logic except dialog creation. * plug-ins/helpbrowser/helpbrowser.c: don't try to call a running help browser and don't install any menu path (all done in app/gimphelp.[ch] now).
1999-09-28 01:58:10 +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 ());
}
1999-10-27 02:27:27 +08:00
if (title)
{
gimp_context_set_pattern (psp->context, active);
}
/* 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 */
label_box = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (psp->options_box), label_box, FALSE, FALSE, 2);
app/airbrush.c app/apptypes.h app/brushes_cmds.c 1999-11-14 Michael Natterer <mitch@gimp.org> * app/airbrush.c * app/apptypes.h * app/brushes_cmds.c * tools/pdbgen/pdb/brushes.pdb * app/bucket_fill.c * app/clone.c * app/gimpbrushpipe.c * app/paint_core.c * app/patterns.h * app/patterns_cmds.c * tools/pdbgen/pdb/patterns.pdb: removed the GimpBrushP and GPatternP types and use ordinary pointers instead. The following stuff makes the "no_data" behaviour consistent. As a side-effect it should make the gimp work when there are _really_ no brushes/patterns/gradients. * app/brush_select.c * app/pattern_select.c: set the initial brush/pattern name to "No Brushes/Patterns available" instead of "Active". * app/devices.c: set the device contexts' brush/pattern/gradient names if we started with no_data, so we find them on refresh. * app/gimpbrushlist.c: set the name of the standard_brush to "Standard". * app/gimpcontext.c: don't replace the current brush/pattern/gradient's name if the new one to be set is the standard one. Together with the change in devices.c, this ensures that we get what is set in devicerc. Minor fixes. * app/gradient.c: changed gradients_init() to work like the other data init functions. Only insert a default gradient in the gradients list when the editor is opened (this means that the gradients now behave like brushes/patterns when we start with "no_data"). New function gradient_update() avoids tons of useless redraws of all clist gradient previews whenever the gradient editor wants to update it's large preview. * app/gradient_select.c: don't segfault when the user tries to drag from an empty gradient list. * app/patterns.c: set the index of the standard_pattern to -1 to indicate that it's not part of the pattern list.
1999-11-14 18:50:19 +08:00
psp->pattern_name = gtk_label_new (_("No Patterns available"));
gtk_box_pack_start (GTK_BOX (label_box), psp->pattern_name, FALSE, FALSE, 4);
psp->pattern_size = gtk_label_new ("(0 X 0)");
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
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 */
/* Get the initial pattern extents */
1999-10-27 02:27:27 +08:00
psp->cell_width = MIN_CELL_SIZE;
psp->cell_height = MIN_CELL_SIZE;
1997-11-25 06:05:25 +08:00
psp->preview = gtk_preview_new (GTK_PREVIEW_COLOR);
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);
gtk_signal_connect (GTK_OBJECT (psp->preview), "size_allocate",
1999-10-27 02:27:27 +08:00
GTK_SIGNAL_FUNC (pattern_select_resize),
psp);
1997-11-25 06:05:25 +08:00
1999-10-28 23:05:49 +08:00
/* dnd stuff */
gtk_drag_source_set (psp->preview,
GDK_BUTTON2_MASK,
preview_target_table, preview_n_targets,
GDK_ACTION_COPY);
gimp_dnd_pattern_source_set (psp->preview, pattern_select_drag_pattern, psp);
1999-10-28 23:05:49 +08:00
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);
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);
gtk_widget_show (frame);
1997-11-25 06:05:25 +08:00
gtk_widget_show (psp->options_box);
gtk_widget_show (vbox);
/* add callbacks to keep the display area current */
psp->name_changed_handler_id =
gimp_container_add_handler
(GIMP_CONTAINER (global_pattern_list), "name_changed",
GTK_SIGNAL_FUNC (pattern_select_pattern_dirty_callback),
psp);
gtk_signal_connect (GTK_OBJECT (global_pattern_list), "add",
GTK_SIGNAL_FUNC (pattern_added_callback),
psp);
gtk_signal_connect (GTK_OBJECT (global_pattern_list), "remove",
GTK_SIGNAL_FUNC (pattern_removed_callback),
psp);
1997-11-25 06:05:25 +08:00
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)
app/airbrush.c app/apptypes.h app/brushes_cmds.c 1999-11-14 Michael Natterer <mitch@gimp.org> * app/airbrush.c * app/apptypes.h * app/brushes_cmds.c * tools/pdbgen/pdb/brushes.pdb * app/bucket_fill.c * app/clone.c * app/gimpbrushpipe.c * app/paint_core.c * app/patterns.h * app/patterns_cmds.c * tools/pdbgen/pdb/patterns.pdb: removed the GimpBrushP and GPatternP types and use ordinary pointers instead. The following stuff makes the "no_data" behaviour consistent. As a side-effect it should make the gimp work when there are _really_ no brushes/patterns/gradients. * app/brush_select.c * app/pattern_select.c: set the initial brush/pattern name to "No Brushes/Patterns available" instead of "Active". * app/devices.c: set the device contexts' brush/pattern/gradient names if we started with no_data, so we find them on refresh. * app/gimpbrushlist.c: set the name of the standard_brush to "Standard". * app/gimpcontext.c: don't replace the current brush/pattern/gradient's name if the new one to be set is the standard one. Together with the change in devices.c, this ensures that we get what is set in devicerc. Minor fixes. * app/gradient.c: changed gradients_init() to work like the other data init functions. Only insert a default gradient in the gradients list when the editor is opened (this means that the gradients now behave like brushes/patterns when we start with "no_data"). New function gradient_update() avoids tons of useless redraws of all clist gradient previews whenever the gradient editor wants to update it's large preview. * app/gradient_select.c: don't segfault when the user tries to drag from an empty gradient list. * app/patterns.c: set the index of the standard_pattern to -1 to indicate that it's not part of the pattern list.
1999-11-14 18:50:19 +08:00
pattern_select_select (psp, active);
1997-11-25 06:05:25 +08:00
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;
}
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));
}
gimp_container_remove_handler (GIMP_CONTAINER (global_pattern_list),
psp->name_changed_handler_id);
gtk_signal_disconnect_by_data (GTK_OBJECT (global_pattern_list), psp);
1999-10-27 02:27:27 +08:00
g_free (psp);
}
void
pattern_select_freeze_all (void)
{
PatternSelect *psp;
GSList *list;
for (list = pattern_active_dialogs; list; list = g_slist_next (list))
{
psp = (PatternSelect *) list->data;
psp->freeze = TRUE;
}
}
void
pattern_select_thaw_all (void)
{
PatternSelect *psp;
GSList *list;
for (list = pattern_active_dialogs; list; list = g_slist_next (list))
{
psp = (PatternSelect *) list->data;
psp->freeze = FALSE;
preview_calc_scrollbar (psp);
}
}
1999-10-27 02:27:27 +08:00
/* 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)
{
gchar *name;
ProcRecord *prec = NULL;
GimpPattern *pattern;
gint nreturn_vals;
1999-10-27 02:27:27 +08:00
static gboolean busy = FALSE;
/* Any procs registered to callback? */
Argument *return_vals;
1999-10-27 02:27:27 +08:00
if (!psp || !psp->callback_name || busy)
return;
1999-10-27 02:27:27 +08:00
busy = TRUE;
name = psp->callback_name;
1999-10-27 02:27:27 +08:00
pattern = gimp_context_get_pattern (psp->context);
/* If its still registered run it */
1999-10-27 02:27:27 +08:00
prec = procedural_db_lookup (name);
1999-10-27 02:27:27 +08:00
if (prec && pattern)
{
1999-10-27 02:27:27 +08:00
return_vals =
procedural_db_run_proc (name,
&nreturn_vals,
PDB_STRING, GIMP_OBJECT (pattern)->name,
1999-10-28 23:05:49 +08:00
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);
if (!return_vals || return_vals[0].value.pdb_int != PDB_SUCCESS)
g_warning ("failed to run pattern callback function");
procedural_db_destroy_args (return_vals, nreturn_vals);
}
1999-10-27 02:27:27 +08:00
busy = FALSE;
}
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);
1999-10-27 02:27:27 +08:00
name = psp->callback_name;
1999-10-27 02:27:27 +08:00
if (name)
{
prec = procedural_db_lookup (name);
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
*/
static GimpPattern *
pattern_select_drag_pattern (GtkWidget *widget,
gpointer data)
{
PatternSelect *psp;
psp = (PatternSelect *) data;
return psp->dnd_pattern;
}
1999-10-28 23:05:49 +08:00
static void
pattern_select_drop_pattern (GtkWidget *widget,
GimpPattern *pattern,
gpointer data)
1999-10-28 23:05:49 +08:00
{
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,
GimpPattern *pattern,
1999-10-27 02:27:27 +08:00
PatternSelect *psp)
{
if (pattern)
{
app/airbrush.c app/apptypes.h app/brushes_cmds.c 1999-11-14 Michael Natterer <mitch@gimp.org> * app/airbrush.c * app/apptypes.h * app/brushes_cmds.c * tools/pdbgen/pdb/brushes.pdb * app/bucket_fill.c * app/clone.c * app/gimpbrushpipe.c * app/paint_core.c * app/patterns.h * app/patterns_cmds.c * tools/pdbgen/pdb/patterns.pdb: removed the GimpBrushP and GPatternP types and use ordinary pointers instead. The following stuff makes the "no_data" behaviour consistent. As a side-effect it should make the gimp work when there are _really_ no brushes/patterns/gradients. * app/brush_select.c * app/pattern_select.c: set the initial brush/pattern name to "No Brushes/Patterns available" instead of "Active". * app/devices.c: set the device contexts' brush/pattern/gradient names if we started with no_data, so we find them on refresh. * app/gimpbrushlist.c: set the name of the standard_brush to "Standard". * app/gimpcontext.c: don't replace the current brush/pattern/gradient's name if the new one to be set is the standard one. Together with the change in devices.c, this ensures that we get what is set in devicerc. Minor fixes. * app/gradient.c: changed gradients_init() to work like the other data init functions. Only insert a default gradient in the gradients list when the editor is opened (this means that the gradients now behave like brushes/patterns when we start with "no_data"). New function gradient_update() avoids tons of useless redraws of all clist gradient previews whenever the gradient editor wants to update it's large preview. * app/gradient_select.c: don't segfault when the user tries to drag from an empty gradient list. * app/patterns.c: set the index of the standard_pattern to -1 to indicate that it's not part of the pattern list.
1999-11-14 18:50:19 +08:00
pattern_select_select (psp, pattern);
if (psp->callback_name)
pattern_change_callbacks (psp, FALSE);
}
1999-10-27 02:27:27 +08:00
}
static void
pattern_select_select (PatternSelect *psp,
GimpPattern *pattern)
1999-10-27 02:27:27 +08:00
{
app/airbrush.c app/apptypes.h app/brushes_cmds.c 1999-11-14 Michael Natterer <mitch@gimp.org> * app/airbrush.c * app/apptypes.h * app/brushes_cmds.c * tools/pdbgen/pdb/brushes.pdb * app/bucket_fill.c * app/clone.c * app/gimpbrushpipe.c * app/paint_core.c * app/patterns.h * app/patterns_cmds.c * tools/pdbgen/pdb/patterns.pdb: removed the GimpBrushP and GPatternP types and use ordinary pointers instead. The following stuff makes the "no_data" behaviour consistent. As a side-effect it should make the gimp work when there are _really_ no brushes/patterns/gradients. * app/brush_select.c * app/pattern_select.c: set the initial brush/pattern name to "No Brushes/Patterns available" instead of "Active". * app/devices.c: set the device contexts' brush/pattern/gradient names if we started with no_data, so we find them on refresh. * app/gimpbrushlist.c: set the name of the standard_brush to "Standard". * app/gimpcontext.c: don't replace the current brush/pattern/gradient's name if the new one to be set is the standard one. Together with the change in devices.c, this ensures that we get what is set in devicerc. Minor fixes. * app/gradient.c: changed gradients_init() to work like the other data init functions. Only insert a default gradient in the gradients list when the editor is opened (this means that the gradients now behave like brushes/patterns when we start with "no_data"). New function gradient_update() avoids tons of useless redraws of all clist gradient previews whenever the gradient editor wants to update it's large preview. * app/gradient_select.c: don't segfault when the user tries to drag from an empty gradient list. * app/patterns.c: set the index of the standard_pattern to -1 to indicate that it's not part of the pattern list.
1999-11-14 18:50:19 +08:00
gint index;
1999-10-27 02:27:27 +08:00
gint row, col;
1999-10-28 23:05:49 +08:00
gint scroll_offset = 0;
1999-10-27 02:27:27 +08:00
index = gimp_container_get_child_index (global_pattern_list,
GIMP_OBJECT (pattern));
app/airbrush.c app/apptypes.h app/brushes_cmds.c 1999-11-14 Michael Natterer <mitch@gimp.org> * app/airbrush.c * app/apptypes.h * app/brushes_cmds.c * tools/pdbgen/pdb/brushes.pdb * app/bucket_fill.c * app/clone.c * app/gimpbrushpipe.c * app/paint_core.c * app/patterns.h * app/patterns_cmds.c * tools/pdbgen/pdb/patterns.pdb: removed the GimpBrushP and GPatternP types and use ordinary pointers instead. The following stuff makes the "no_data" behaviour consistent. As a side-effect it should make the gimp work when there are _really_ no brushes/patterns/gradients. * app/brush_select.c * app/pattern_select.c: set the initial brush/pattern name to "No Brushes/Patterns available" instead of "Active". * app/devices.c: set the device contexts' brush/pattern/gradient names if we started with no_data, so we find them on refresh. * app/gimpbrushlist.c: set the name of the standard_brush to "Standard". * app/gimpcontext.c: don't replace the current brush/pattern/gradient's name if the new one to be set is the standard one. Together with the change in devices.c, this ensures that we get what is set in devicerc. Minor fixes. * app/gradient.c: changed gradients_init() to work like the other data init functions. Only insert a default gradient in the gradients list when the editor is opened (this means that the gradients now behave like brushes/patterns when we start with "no_data"). New function gradient_update() avoids tons of useless redraws of all clist gradient previews whenever the gradient editor wants to update it's large preview. * app/gradient_select.c: don't segfault when the user tries to drag from an empty gradient list. * app/patterns.c: set the index of the standard_pattern to -1 to indicate that it's not part of the pattern list.
1999-11-14 18:50:19 +08:00
if (index < 0)
return;
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
}
static void
pattern_select_pattern_dirty_callback (GimpPattern *pattern,
PatternSelect *psp)
{
gint index;
gboolean redraw;
if (!psp || psp->freeze)
return;
index = gimp_container_get_child_index (global_pattern_list,
GIMP_OBJECT (pattern));
redraw = (pattern != gimp_context_get_pattern (psp->context));
display_pattern (psp, pattern,
index % (psp->NUM_PATTERN_COLUMNS),
index / (psp->NUM_PATTERN_COLUMNS));
}
static void
pattern_added_callback (GimpContainer *container,
GimpPattern *pattern,
PatternSelect *psp)
{
if (psp->freeze)
return;
preview_calc_scrollbar (psp);
}
static void
pattern_removed_callback (GimpContainer *container,
GimpPattern *pattern,
PatternSelect *psp)
{
if (psp->freeze)
return;
preview_calc_scrollbar (psp);
}
1999-10-27 02:27:27 +08:00
typedef struct
{
PatternSelect *psp;
int x;
int y;
GimpPattern *pattern;
} popup_timeout_args_t;
static gboolean
pattern_popup_timeout (gpointer data)
1997-11-25 06:05:25 +08:00
{
popup_timeout_args_t *args = data;
PatternSelect *psp = args->psp;
GimpPattern *pattern = args->pattern;
gint x, y;
gint x_org, y_org;
gint scr_w, scr_h;
gchar *src, *buf;
1997-12-18 12:19:11 +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;
1997-11-25 06:05:25 +08:00
psp->pattern_popup = gtk_window_new (GTK_WINDOW_POPUP);
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 ();
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;
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);
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];
}
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;
}
g_free (buf);
1997-11-25 06:05:25 +08:00
/* Draw the pattern preview */
gtk_widget_draw (psp->pattern_preview, NULL);
return FALSE; /* don't repeat */
}
static void
1999-10-27 02:27:27 +08:00
pattern_popup_open (PatternSelect *psp,
gint x,
gint y,
GimpPattern *pattern)
{
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
{
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,
GimpPattern *pattern,
1999-10-27 02:27:27 +08:00
gint col,
gint row)
1997-11-25 06:05:25 +08:00
{
TempBuf *pattern_buf;
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;
1999-10-27 02:27:27 +08:00
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;
ystart = CLAMP (offset_y, 0, psp->preview->allocation.height);
yend = CLAMP (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
{
GList *list = GIMP_LIST (global_pattern_list)->list;
gint row, col;
GimpPattern *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;
for (; list; list = g_list_next (list))
1997-11-25 06:05:25 +08:00
{
pattern = (GimpPattern *) list->data;
1997-11-25 06:05:25 +08:00
/* Display the pattern */
display_pattern (psp, pattern, col, row);
/* increment the counts */
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
if (psp->old_col != col || psp->old_row != row)
1997-11-25 06:05:25 +08:00
{
/* remove the old selection */
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
ystart = CLAMP (offset_y , 0, psp->preview->allocation.height);
yend = CLAMP (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;
ystart = CLAMP (offset_y , 0, psp->preview->allocation.height);
yend = CLAMP (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);
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
{
GimpPattern *pattern;
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 */
gtk_label_set_text (GTK_LABEL (psp->pattern_name),
GIMP_OBJECT (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);
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 = ((GIMP_CONTAINER (global_pattern_list)->num_children +
psp->NUM_PATTERN_COLUMNS - 1) /
1999-10-27 02:27:27 +08:00
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)
{
/* calculate the best-fit approximation... */
1997-11-25 06:05:25 +08:00
gint wid;
gint now;
gint cell_size;
1997-11-25 06:05:25 +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
{
if ((wid % now) < (wid % cell_size)) cell_size = now;
if ((wid % cell_size) == 0)
1997-11-25 06:05:25 +08:00
break;
}
psp->NUM_PATTERN_COLUMNS =
(gint) (wid / cell_size);
psp->NUM_PATTERN_ROWS =
(gint) ((GIMP_CONTAINER (global_pattern_list)->num_children +
psp->NUM_PATTERN_COLUMNS - 1) /
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;
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;
GimpPattern *pattern;
gint row, col, index;
1997-11-25 06:05:25 +08:00
switch (event->type)
{
case GDK_BUTTON_PRESS:
bevent = (GdkEventButton *) event;
col = bevent->x / psp->cell_width;
row = (bevent->y + psp->scroll_offset) / psp->cell_height;
index = row * psp->NUM_PATTERN_COLUMNS + col;
pattern =
(GimpPattern *) gimp_container_get_child_by_index (global_pattern_list,
index);
if (pattern)
psp->dnd_pattern = pattern;
else
psp->dnd_pattern = gimp_context_get_pattern (psp->context);
1997-11-25 06:05:25 +08:00
if (bevent->button == 1)
{
/* Get the pattern and display the popup pattern preview */
if (pattern)
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
}
}
/* 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);
}
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;
GimpPattern *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);
1997-11-25 06:05:25 +08:00
if (active)
{
index = gimp_container_get_child_index (global_pattern_list,
GIMP_OBJECT (active));
app/airbrush.c app/apptypes.h app/brushes_cmds.c 1999-11-14 Michael Natterer <mitch@gimp.org> * app/airbrush.c * app/apptypes.h * app/brushes_cmds.c * tools/pdbgen/pdb/brushes.pdb * app/bucket_fill.c * app/clone.c * app/gimpbrushpipe.c * app/paint_core.c * app/patterns.h * app/patterns_cmds.c * tools/pdbgen/pdb/patterns.pdb: removed the GimpBrushP and GPatternP types and use ordinary pointers instead. The following stuff makes the "no_data" behaviour consistent. As a side-effect it should make the gimp work when there are _really_ no brushes/patterns/gradients. * app/brush_select.c * app/pattern_select.c: set the initial brush/pattern name to "No Brushes/Patterns available" instead of "Active". * app/devices.c: set the device contexts' brush/pattern/gradient names if we started with no_data, so we find them on refresh. * app/gimpbrushlist.c: set the name of the standard_brush to "Standard". * app/gimpcontext.c: don't replace the current brush/pattern/gradient's name if the new one to be set is the standard one. Together with the change in devices.c, this ensures that we get what is set in devicerc. Minor fixes. * app/gradient.c: changed gradients_init() to work like the other data init functions. Only insert a default gradient in the gradients list when the editor is opened (this means that the gradients now behave like brushes/patterns when we start with "no_data"). New function gradient_update() avoids tons of useless redraws of all clist gradient previews whenever the gradient editor wants to update it's large preview. * app/gradient_select.c: don't segfault when the user tries to drag from an empty gradient list. * app/patterns.c: set the index of the standard_pattern to -1 to indicate that it's not part of the pattern list.
1999-11-14 18:50:19 +08:00
if (index < 0)
return;
1999-10-27 02:27:27 +08:00
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
}
}
1999-10-27 02:27:27 +08:00
static void
pattern_select_close_callback (GtkWidget *widget,
gpointer data)
{
PatternSelect *psp;
1999-10-27 02:27:27 +08:00
psp = (PatternSelect *) data;
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)
{
1999-10-27 02:27:27 +08:00
PatternSelect *psp;
GSList *list;
1999-10-27 02:27:27 +08:00
/* re-init the pattern list */
patterns_init (FALSE);
1999-10-27 02:27:27 +08:00
for (list = pattern_active_dialogs; list; list = g_slist_next (list))
{
1999-10-27 02:27:27 +08:00
psp = (PatternSelect *) list->data;
app/Makefile.am app/gimphelp.[ch] new files 1999-09-27 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/gimphelp.[ch] * app/gimpui.[ch]: new files * app/interface.[ch] * app/preferences_dialog.[ch] The GIMP Help System part 1: Press "F1" in any dialog to pop up the help page for this dialog. Moved the widget constructors from preferences_dialog.[ch] and the query boxes from interface.[ch] to gimpui.[ch]. The dialog constructors take a help_func and a help_data parameter and install the "F1" accelerator which emits the new "help" signal. The "help" signal callback calls help_func(help_data) which finally has to call gimp_help() which in turn invokes the help browser. Still have to find a proper way to (1) prevent "F1" being assigned to some menu item and (2) to catch "F1" while browsing the menu trees in order to pop up the help for the selected item. * app/menus.c: a <Toolbox>/File/Help... menu item. * app/commands.[ch]: a command callback for the "Help..." menu item. * app/gimprc.[ch]: new boolean gimprc variable "use_help". * app/info_dialog.[ch]: pass a help function and data to the info dialog constructor. * app/tools.[ch]: store the tools help page names in the tool info structure. Export a special tools_help_func() which shows the help page for the active tool. * app/[all files calling a dialog constructor]: pass the dialog's help page to the constructor. Most dialogs are now created by gimp_dialog_new() which also sets up the action_area and the WM delete event callback, so I removed the resp. code from these files. Fixed some minor bugs and did some other stuff but didn't change any logic except dialog creation. * plug-ins/helpbrowser/helpbrowser.c: don't try to call a running help browser and don't install any menu path (all done in app/gimphelp.[ch] now).
1999-09-28 01:58:10 +08:00
1999-10-27 02:27:27 +08:00
/* recalculate scrollbar extents */
preview_calc_scrollbar (psp);
}
}