added pygimp to tree, as organised with Marc Lehmann. I have not hooked it
1999-09-05 James Henstridge <james@daa.com.au> * plug-ins/pygimp/*: added pygimp to tree, as organised with Marc Lehmann. I have not hooked it into the main makefile yet. That should not be difficult though.
This commit is contained in:

committed by
James Henstridge

parent
34b6cabd7a
commit
910e7cb689
@ -1,3 +1,9 @@
|
||||
1999-09-05 James Henstridge <james@daa.com.au>
|
||||
|
||||
* plug-ins/pygimp/*: added pygimp to tree, as organised with Marc
|
||||
Lehmann. I have not hooked it into the main makefile yet. That
|
||||
should not be difficult though.
|
||||
|
||||
Sun Sep 5 14:48:30 MEST 1999 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* app/gimpcontextpreview.c: small cosmetic change
|
||||
|
17
plug-ins/pygimp/.cvsignore
Normal file
17
plug-ins/pygimp/.cvsignore
Normal file
@ -0,0 +1,17 @@
|
||||
Makefile
|
||||
#Makefile.in
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.so
|
||||
configure
|
||||
config.log
|
||||
config.h
|
||||
config.cache
|
||||
stamp-h
|
||||
config.h.in
|
||||
stamp-h.in
|
||||
aclocal.m4
|
||||
INSTALL
|
||||
mkinstalldirs
|
||||
install-sh
|
||||
|
0
plug-ins/pygimp/AUTHORS
Normal file
0
plug-ins/pygimp/AUTHORS
Normal file
107
plug-ins/pygimp/ChangeLog
Normal file
107
plug-ins/pygimp/ChangeLog
Normal file
@ -0,0 +1,107 @@
|
||||
1999-07-08 James Henstridge <james@daa.com.au>
|
||||
|
||||
* plug-ins/shadow_bevel.py: added {disable,enable}_undo() calls. Also
|
||||
made it possible to turn off the creation of a shadow.
|
||||
|
||||
* plug-ins/foggify.py: added disable_undo() and enable_undo() calls
|
||||
round the plugin code.
|
||||
|
||||
* plug-ins/Makefile.am: forgot to add foggify and shadow_bevel to
|
||||
the EXTRA_DIST list.
|
||||
|
||||
* gimpui.py: fixed some small bugs that caused an exception when
|
||||
loading on some versions of python. Weird thing is, it did not
|
||||
cause problems on my computer (using 1.5.1)
|
||||
|
||||
1999-07-05 James Henstridge <james@daa.com.au>
|
||||
|
||||
* plug-ins/foggify.py, plug-ins/shadow_bevel.py: two new example
|
||||
scripts.
|
||||
|
||||
1999-07-04 James Henstridge <james@daa.com.au>
|
||||
|
||||
* gimpmodule.c: added support for parasites. This new code is
|
||||
conditionally compiled if GIMP_HAVE_PARASITES is defined.
|
||||
Added other gimp 1.1 features to gimpmodule.
|
||||
|
||||
1999-07-03 James Henstridge <james@daa.com.au>
|
||||
|
||||
* gimpmodule.c (initgimp): added {major,minor,micro}_version constants
|
||||
to gimpmodule.
|
||||
(*) removed all the empty __doc__ strings -- they were just wasting
|
||||
space, and I have other docs in there now.
|
||||
|
||||
* plug-ins/clothify.py (python_clothify): same here.
|
||||
|
||||
* plug-ins/sphere.py (python_sphere): some small hacks to get the
|
||||
plugin to work with both gimp 1.0 and 1.1 -- using the pattern
|
||||
"if pdb.gimp_whatever.nparams == n" to check if the img parameter
|
||||
should be removed.
|
||||
|
||||
* plug-ins/pdbbrowse.py (BrowseWin.extension_pdb_browse): fixed
|
||||
small bug.
|
||||
|
||||
1999-07-02 James Henstridge <james@daa.com.au>
|
||||
|
||||
* plug-ins/whirlpinch.py (python_whirl_pinch): adjusted plug in to
|
||||
work with drawable changes.
|
||||
|
||||
* gimpmodule.c: removed the drawable type -- now only layer or channel
|
||||
types are used. Also moved the drawable type's methods to both the
|
||||
layer and channel object types. Also added some of the attributes of
|
||||
the drawable object to layer and channel objects (some aren't needed
|
||||
anymore, since layers are clearly defined as layers, and channels
|
||||
as channels).
|
||||
Make tile and pixel region objects keep a reference to their
|
||||
associated drawable.
|
||||
Added attributes has_alpha, is_colour, is_grey and is_indexed to
|
||||
layer and channel objects.
|
||||
|
||||
1999-06-22 James Henstridge <james@daa.com.au>
|
||||
|
||||
* gimpplugin.py: renamed from plugin.py. This is mainly to reduce
|
||||
namespace polution.
|
||||
|
||||
* getvals.py: removed file. It has been replaced by the much more
|
||||
functional gimpfu module.
|
||||
|
||||
* plug-ins/gimpcons.py: added a browse button that will display the
|
||||
pdbbrowse window, which can then be used to choose a pdb function.
|
||||
The selected pdb function gets its prototype inserted on the
|
||||
command line.
|
||||
|
||||
* plug-ins/pdbbrowse.py: converted to use GTK+ widgets and gimpfu.
|
||||
|
||||
* plug-ins/gimpcons.py: converted to use gimpfu and gtkcons.py.
|
||||
|
||||
* plug-ings/gtkcons.py: a GTK replacement for tkcons.py.
|
||||
|
||||
* plug-ins/whirlpinch.py, plug-ins/sphere.py: converted these two
|
||||
to use gimpfu.
|
||||
|
||||
* gimpshelf.py (shelf): some changes so that the gimp internal types
|
||||
will pickle correctly.
|
||||
|
||||
* gimpmodule.c (initgimp): export the type objects for gimpmodule's
|
||||
internal types. This is mainly to help get pickling to work
|
||||
correctly.
|
||||
(_id2*): new functions to help convert id's to the builtin types.
|
||||
|
||||
* plug-ins/clothify.py: converted to use gimpfu module.
|
||||
|
||||
1999-06-21 James Henstridge <james@daa.com.au>
|
||||
|
||||
* gimpfu.py: a simplified interface to writing GIMP plugins. It
|
||||
handles all the user interaction stuff and saving the last used
|
||||
values. It uses pygtk, so should match the interface of the rest
|
||||
of gimp.
|
||||
|
||||
* gimpui.py: new file that implements a number of useful widgets
|
||||
for use with the interfaces of plugins. It requires pygtk.
|
||||
|
||||
* gimpmodule.c (tuple_to_GParam): accept None for layer, channel
|
||||
or drawable arguments to PDB functions. This value gets treated
|
||||
like an ID of -1.
|
||||
(img_cmp, lay_cmp, chn_cmp, drw_cmp): added compare functions so
|
||||
that the == operator works as expected with those object types.
|
||||
|
17
plug-ins/pygimp/Makefile.am.14
Normal file
17
plug-ins/pygimp/Makefile.am.14
Normal file
@ -0,0 +1,17 @@
|
||||
SUBDIRS = doc plug-ins
|
||||
|
||||
INCLUDES = $(PYTHON_INCLUDES) $(PYTHON_CFLAGS) $(GIMP_CFLAGS_NOUI)
|
||||
|
||||
pyexec_PROGRAMS = gimpmodule$(SO)
|
||||
|
||||
gimpmodule__SO__SOURCES = gimpmodule.c
|
||||
gimpmodule__SO__LDADD = $(GIMP_LIBS_NOUI)
|
||||
gimpmodule__SO__LINK = $(PYTHON_LINK)
|
||||
|
||||
python_PYTHON = gimpplugin.py gimpenums.py gimpshelf.py \
|
||||
gimpui.py gimpfu.py
|
||||
|
||||
EXTRA_DIST = pygimp.spec
|
||||
|
||||
snap:
|
||||
$(MAKE) dist distdir=$(PACKAGE)-SNAP-`date +"%Y%m%d"`
|
457
plug-ins/pygimp/Makefile.in
Normal file
457
plug-ins/pygimp/Makefile.in
Normal file
@ -0,0 +1,457 @@
|
||||
# This has been modified slightly. The Makefile.am file has been moved to
|
||||
# Makefile.am.14 because it uses some non standard extensions. This should
|
||||
# be resolved when automake-1.5 comes out.
|
||||
|
||||
# Makefile.in generated automatically by automake 1.4 from Makefile.am
|
||||
|
||||
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
|
||||
SHELL = @SHELL@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = @bindir@
|
||||
sbindir = @sbindir@
|
||||
libexecdir = @libexecdir@
|
||||
datadir = @datadir@
|
||||
sysconfdir = @sysconfdir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
localstatedir = @localstatedir@
|
||||
libdir = @libdir@
|
||||
infodir = @infodir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
oldincludedir = /usr/include
|
||||
|
||||
DESTDIR =
|
||||
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
|
||||
top_builddir = .
|
||||
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
transform = @program_transform_name@
|
||||
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
CC = @CC@
|
||||
GIMPTOOL = @GIMPTOOL@
|
||||
GIMP_CFLAGS_NOUI = @GIMP_CFLAGS_NOUI@
|
||||
GIMP_LIBS_NOUI = @GIMP_LIBS_NOUI@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
OPT = @OPT@
|
||||
PACKAGE = @PACKAGE@
|
||||
PYTHON = @PYTHON@
|
||||
PYTHON_CFLAGS = @PYTHON_CFLAGS@
|
||||
PYTHON_INCLUDES = @PYTHON_INCLUDES@
|
||||
PYTHON_LINK = @PYTHON_LINK@
|
||||
SO = @SO@
|
||||
VERSION = @VERSION@
|
||||
pluginexecdir = @pluginexecdir@
|
||||
pyexecdir = @pyexecdir@
|
||||
pythondir = @pythondir@
|
||||
|
||||
SUBDIRS = doc plug-ins
|
||||
|
||||
INCLUDES = $(PYTHON_INCLUDES) $(PYTHON_CFLAGS) $(GIMP_CFLAGS_NOUI)
|
||||
|
||||
pyexec_PROGRAMS = gimpmodule$(SO)
|
||||
|
||||
gimpmodule__SO__SOURCES = gimpmodule.c
|
||||
gimpmodule__SO__LDADD = $(GIMP_LIBS_NOUI)
|
||||
gimpmodule__SO__LINK = $(PYTHON_LINK)
|
||||
|
||||
python_PYTHON = gimpplugin.py gimpenums.py gimpshelf.py gimpui.py gimpfu.py
|
||||
|
||||
|
||||
EXTRA_DIST = pygimp.spec
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_CLEAN_FILES =
|
||||
PROGRAMS = $(pyexec_PROGRAMS)
|
||||
|
||||
|
||||
DEFS = @DEFS@ -I. -I$(srcdir)
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
gimpmodule__SO__OBJECTS = gimpmodule.o
|
||||
gimpmodule__SO__DEPENDENCIES =
|
||||
gimpmodule__SO__LDFLAGS =
|
||||
CFLAGS = @CFLAGS@
|
||||
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
|
||||
PYTHONFILES = gimpplugin.py gimpenums.py gimpshelf.py gimpui.py \
|
||||
gimpfu.py
|
||||
py_compile = $(top_srcdir)/py-compile
|
||||
DIST_COMMON = README $(PYTHONFILES) AUTHORS COPYING ChangeLog INSTALL \
|
||||
Makefile.am.14 Makefile.in NEWS aclocal.m4 configure configure.in \
|
||||
install-sh missing mkinstalldirs py-compile
|
||||
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
TAR = tar
|
||||
GZIP_ENV = --best
|
||||
SOURCES = $(gimpmodule__SO__SOURCES)
|
||||
OBJECTS = $(gimpmodule__SO__OBJECTS)
|
||||
|
||||
all: all-redirect
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .S .c .o .s
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
$(ACLOCAL_M4): configure.in
|
||||
cd $(srcdir) && $(ACLOCAL)
|
||||
|
||||
config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
$(SHELL) ./config.status --recheck
|
||||
$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
|
||||
cd $(srcdir) && $(AUTOCONF)
|
||||
|
||||
mostlyclean-pyexecPROGRAMS:
|
||||
|
||||
clean-pyexecPROGRAMS:
|
||||
-test -z "$(pyexec_PROGRAMS)" || rm -f $(pyexec_PROGRAMS)
|
||||
|
||||
distclean-pyexecPROGRAMS:
|
||||
|
||||
maintainer-clean-pyexecPROGRAMS:
|
||||
|
||||
install-pyexecPROGRAMS: $(pyexec_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(pyexecdir)
|
||||
@list='$(pyexec_PROGRAMS)'; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pyexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
|
||||
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(pyexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
|
||||
else :; fi; \
|
||||
done
|
||||
|
||||
uninstall-pyexecPROGRAMS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
list='$(pyexec_PROGRAMS)'; for p in $$list; do \
|
||||
rm -f $(DESTDIR)$(pyexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
|
||||
done
|
||||
|
||||
.c.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
.s.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
.S.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.o core *.core
|
||||
|
||||
clean-compile:
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
maintainer-clean-compile:
|
||||
|
||||
gimpmodule$(SO): $(gimpmodule__SO__OBJECTS) $(gimpmodule__SO__DEPENDENCIES)
|
||||
@rm -f gimpmodule$(SO)
|
||||
$(gimpmodule__SO__LINK) $(gimpmodule__SO__LDFLAGS) $(gimpmodule__SO__OBJECTS) $(gimpmodule__SO__LDADD) $(LIBS)
|
||||
|
||||
mostlyclean-pythonPYTHON:
|
||||
|
||||
clean-pythonPYTHON:
|
||||
|
||||
distclean-pythonPYTHON:
|
||||
|
||||
maintainer-clean-pythonPYTHON:
|
||||
|
||||
install-pythonPYTHON: $(python_PYTHON)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(pythondir)
|
||||
@list='$(python_PYTHON)'; for p in $$list; do\
|
||||
if test -f $(srcdir)/$$p; then \
|
||||
echo " $(INSTALL_PROGRAM) $(srcdir)/$$p $(DESTDIR)$(pythondir)/$$p"; \
|
||||
$(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pythondir)/$$p; \
|
||||
else :; fi; \
|
||||
done
|
||||
@PYTHON=$(PYTHON) $(py_compile) --basedir $(DESTDIR)$(pythondir) $(python_PYTHON)
|
||||
|
||||
uninstall-pythonPYTHON:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
list='$(python_PYTHON)'; for p in $$list; do \
|
||||
rm -f $(DESTDIR)$(pythondir)/$$p; \
|
||||
rm -f $(DESTDIR)$(pythondir)/$${p}c; \
|
||||
rm -f $(DESTDIR)$(pythondir)/$${p}o; \
|
||||
done
|
||||
|
||||
# This directory's subdirectories are mostly independent; you can cd
|
||||
# into them and run `make' without going through this Makefile.
|
||||
# To change the values of `make' variables: instead of editing Makefiles,
|
||||
# (1) if the variable is set in `config.status', edit `config.status'
|
||||
# (which will cause the Makefiles to be regenerated when you run `make');
|
||||
# (2) otherwise, pass the desired values on the `make' command line.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
all-recursive install-data-recursive install-exec-recursive \
|
||||
installdirs-recursive install-recursive uninstall-recursive \
|
||||
check-recursive installcheck-recursive info-recursive dvi-recursive:
|
||||
@set fnord $(MAKEFLAGS); amf=$$2; \
|
||||
dot_seen=no; \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
echo "Making $$target in $$subdir"; \
|
||||
if test "$$subdir" = "."; then \
|
||||
dot_seen=yes; \
|
||||
local_target="$$target-am"; \
|
||||
else \
|
||||
local_target="$$target"; \
|
||||
fi; \
|
||||
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
||||
done; \
|
||||
if test "$$dot_seen" = "no"; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
|
||||
fi; test -z "$$fail"
|
||||
|
||||
mostlyclean-recursive clean-recursive distclean-recursive \
|
||||
maintainer-clean-recursive:
|
||||
@set fnord $(MAKEFLAGS); amf=$$2; \
|
||||
dot_seen=no; \
|
||||
rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
rev="$$subdir $$rev"; \
|
||||
test "$$subdir" = "." && dot_seen=yes; \
|
||||
done; \
|
||||
test "$$dot_seen" = "no" && rev=". $$rev"; \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
for subdir in $$rev; do \
|
||||
echo "Making $$target in $$subdir"; \
|
||||
if test "$$subdir" = "."; then \
|
||||
local_target="$$target-am"; \
|
||||
else \
|
||||
local_target="$$target"; \
|
||||
fi; \
|
||||
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
||||
done && test -z "$$fail"
|
||||
tags-recursive:
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
|
||||
done
|
||||
|
||||
tags: TAGS
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP)
|
||||
list='$(SOURCES) $(HEADERS)'; \
|
||||
unique=`for i in $$list; do echo $$i; done | \
|
||||
awk ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
here=`pwd` && cd $(srcdir) \
|
||||
&& mkid -f$$here/ID $$unique $(LISP)
|
||||
|
||||
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
|
||||
fi; \
|
||||
done; \
|
||||
list='$(SOURCES) $(HEADERS)'; \
|
||||
unique=`for i in $$list; do echo $$i; done | \
|
||||
awk ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|
||||
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
|
||||
|
||||
mostlyclean-tags:
|
||||
|
||||
clean-tags:
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID
|
||||
|
||||
maintainer-clean-tags:
|
||||
|
||||
distdir = $(PACKAGE)-$(VERSION)
|
||||
top_distdir = $(distdir)
|
||||
|
||||
# This target untars the dist file and tries a VPATH configuration. Then
|
||||
# it guarantees that the distribution is self-contained by making another
|
||||
# tarfile.
|
||||
distcheck: dist
|
||||
-rm -rf $(distdir)
|
||||
GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
|
||||
mkdir $(distdir)/=build
|
||||
mkdir $(distdir)/=inst
|
||||
dc_install_base=`cd $(distdir)/=inst && pwd`; \
|
||||
cd $(distdir)/=build \
|
||||
&& ../configure --srcdir=.. --prefix=$$dc_install_base \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) check \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) install \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) dist
|
||||
-rm -rf $(distdir)
|
||||
@banner="$(distdir).tar.gz is ready for distribution"; \
|
||||
dashes=`echo "$$banner" | sed s/./=/g`; \
|
||||
echo "$$dashes"; \
|
||||
echo "$$banner"; \
|
||||
echo "$$dashes"
|
||||
dist: distdir
|
||||
-chmod -R a+r $(distdir)
|
||||
GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
|
||||
-rm -rf $(distdir)
|
||||
dist-all: distdir
|
||||
-chmod -R a+r $(distdir)
|
||||
GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
|
||||
-rm -rf $(distdir)
|
||||
distdir: $(DISTFILES)
|
||||
-rm -rf $(distdir)
|
||||
mkdir $(distdir)
|
||||
-chmod 777 $(distdir)
|
||||
@for file in $(DISTFILES); do \
|
||||
d=$(srcdir); \
|
||||
if test -d $$d/$$file; then \
|
||||
cp -pr $$/$$file $(distdir)/$$file; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file || :; \
|
||||
fi; \
|
||||
done
|
||||
for subdir in $(SUBDIRS); do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
test -d $(distdir)/$$subdir \
|
||||
|| mkdir $(distdir)/$$subdir \
|
||||
|| exit 1; \
|
||||
chmod 777 $(distdir)/$$subdir; \
|
||||
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
gimpmodule.o: gimpmodule.c
|
||||
|
||||
info-am:
|
||||
info: info-recursive
|
||||
dvi-am:
|
||||
dvi: dvi-recursive
|
||||
check-am: all-am
|
||||
check: check-recursive
|
||||
installcheck-am:
|
||||
installcheck: installcheck-recursive
|
||||
install-exec-am: install-pyexecPROGRAMS
|
||||
install-exec: install-exec-recursive
|
||||
|
||||
install-data-am: install-pythonPYTHON
|
||||
install-data: install-data-recursive
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
install: install-recursive
|
||||
uninstall-am: uninstall-pyexecPROGRAMS uninstall-pythonPYTHON
|
||||
uninstall: uninstall-recursive
|
||||
all-am: Makefile $(PROGRAMS)
|
||||
all-redirect: all-recursive
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
|
||||
installdirs: installdirs-recursive
|
||||
installdirs-am:
|
||||
$(mkinstalldirs) $(DESTDIR)$(pyexecdir) $(DESTDIR)$(pythondir)
|
||||
|
||||
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
|
||||
|
||||
maintainer-clean-generic:
|
||||
mostlyclean-am: mostlyclean-pyexecPROGRAMS mostlyclean-compile \
|
||||
mostlyclean-pythonPYTHON mostlyclean-tags \
|
||||
mostlyclean-generic
|
||||
|
||||
mostlyclean: mostlyclean-recursive
|
||||
|
||||
clean-am: clean-pyexecPROGRAMS clean-compile clean-pythonPYTHON \
|
||||
clean-tags clean-generic mostlyclean-am
|
||||
|
||||
clean: clean-recursive
|
||||
|
||||
distclean-am: distclean-pyexecPROGRAMS distclean-compile \
|
||||
distclean-pythonPYTHON distclean-tags distclean-generic \
|
||||
clean-am
|
||||
|
||||
distclean: distclean-recursive
|
||||
-rm -f config.status
|
||||
|
||||
maintainer-clean-am: maintainer-clean-pyexecPROGRAMS \
|
||||
maintainer-clean-compile maintainer-clean-pythonPYTHON \
|
||||
maintainer-clean-tags maintainer-clean-generic \
|
||||
distclean-am
|
||||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
|
||||
maintainer-clean: maintainer-clean-recursive
|
||||
-rm -f config.status
|
||||
|
||||
.PHONY: mostlyclean-pyexecPROGRAMS distclean-pyexecPROGRAMS \
|
||||
clean-pyexecPROGRAMS maintainer-clean-pyexecPROGRAMS \
|
||||
uninstall-pyexecPROGRAMS install-pyexecPROGRAMS mostlyclean-compile \
|
||||
distclean-compile clean-compile maintainer-clean-compile \
|
||||
mostlyclean-pythonPYTHON distclean-pythonPYTHON clean-pythonPYTHON \
|
||||
maintainer-clean-pythonPYTHON uninstall-pythonPYTHON \
|
||||
install-pythonPYTHON install-data-recursive uninstall-data-recursive \
|
||||
install-exec-recursive uninstall-exec-recursive installdirs-recursive \
|
||||
uninstalldirs-recursive all-recursive check-recursive \
|
||||
installcheck-recursive info-recursive dvi-recursive \
|
||||
mostlyclean-recursive distclean-recursive clean-recursive \
|
||||
maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
|
||||
distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
|
||||
dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
|
||||
install-exec install-data-am install-data install-am install \
|
||||
uninstall-am uninstall all-redirect all-am all installdirs-am \
|
||||
installdirs mostlyclean-generic distclean-generic clean-generic \
|
||||
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
|
||||
|
||||
|
||||
snap:
|
||||
$(MAKE) dist distdir=$(PACKAGE)-SNAP-`date +"%Y%m%d"`
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
65
plug-ins/pygimp/NEWS
Normal file
65
plug-ins/pygimp/NEWS
Normal file
@ -0,0 +1,65 @@
|
||||
pygimp-0.5: 8-July-1999
|
||||
- Fixed some bugs that I missed in gimpui. It should actually work
|
||||
on other people's systems now (I don't know why it worked on mine).
|
||||
- Included the foggify.py and shadow_bevel.py plugins in the package.
|
||||
- Added a timeout function to flush the displays in the gimpconsole
|
||||
plugin. This way you can see the results of what you type easily.
|
||||
|
||||
pygimp-0.4: 5-July-1999
|
||||
- Removed the drawable type -- now layer or channel objects are used
|
||||
in its place. All drawable methods have been transfered to both
|
||||
the channel and layer objects. The layer and channel objects have
|
||||
the following attributes in common:
|
||||
ID, bpp, has_alpha, height, image, is_color, is_colour, is_gray,
|
||||
is_grey, is_indexed, mask_bounds, name, offsets, opacity
|
||||
This means that the gimp.drawable(layer|channel) command is gone,
|
||||
and so is the gimp.layer(drawable) and gimp.channel(drawable)
|
||||
syntaxes (the gimp.layer and gimp.channel commands still exist).
|
||||
I made this change because the previous setup was confusing, and
|
||||
more complicated than it needed to be.
|
||||
- Removed all tkinter code, and replaced it with pygtk code. There
|
||||
is now also a convenience module gimpfu, which is a simpler
|
||||
interface to
|
||||
|
||||
pygimp-0.3: 8-February-1999
|
||||
- Some small build cleanups. Now you should be able to do the normal
|
||||
./configure ; make ; make install. It should compile fine with
|
||||
GIMP 1.0 (I haven't tested 1.1 series though).
|
||||
- gimpmodule.c now prints exception messages, so now exceptions caused
|
||||
by a plugin will print a stack trace to stdout, and cause gimp to
|
||||
realise the plugin failed.
|
||||
- The disable_undo and enable_undo methods of image now use the
|
||||
stack based enable/disable functions.
|
||||
- Added function names to PyArg_ParseTuple calls, so exceptions
|
||||
are a little easier to understand.
|
||||
- added a spec file for building RPMS for this package.
|
||||
- added gimp.extension_ack, gimp.extension_process,
|
||||
gimp.install_temp_proc and gimp.uninstall_temp_proc which will be
|
||||
useful to implement an interface similar to script-fu's (ie. one
|
||||
copy of python running in the background, responding to requests
|
||||
from the gimp process every now and again).
|
||||
- changed over to using glib's safe memory allocation routines g_new,
|
||||
g_strdup and g_free.
|
||||
- Converted documentation to docbook -- linuxdoc is just about dead.
|
||||
|
||||
pygimp-0.2.0: 19-Nov-1997
|
||||
- implemented pixel regions. You can access them as a mapping. (ie.
|
||||
pr[x,y] is get_pixel, pr[x1:x2,y] is get_row, pr[x, y1:y2] is get_col
|
||||
and pr[x1:x2, y1:y2] is get_rect)
|
||||
- to demonstrate the use of this low level object, I have included a
|
||||
translation of the c plugin Whirl and Pinch.
|
||||
- fixed a problem where I didn't check for a NULL when parsing
|
||||
arguments for a plugin. This caused a crash when you ran a plugin
|
||||
that took a string as an argument was run in interactive mode.
|
||||
|
||||
pygimp-0.1.0: 18-Nov-1997
|
||||
- first public release.
|
||||
- implements images, layers, channels, drawables, tiles, and just about
|
||||
everything except pixel regions.
|
||||
- I have included a number of example plugins:
|
||||
- gimpcons is an interactive python console
|
||||
- pdbbrowse is a browser for the PDB
|
||||
- clothify is a translation of the Script-Fu script
|
||||
- sphere is a translation of the Script-Fu script
|
||||
|
||||
|
29
plug-ins/pygimp/README
Normal file
29
plug-ins/pygimp/README
Normal file
@ -0,0 +1,29 @@
|
||||
Gimp-Python - allows the writing of plugins for Gimp in Python.
|
||||
Copyright (C) 1997-1999 James Henstridge <james@daa.com.au>
|
||||
|
||||
This is the Gimp-Python package. It is free software and is covered
|
||||
by the GNU General Public Licence (A copy of which is in the file
|
||||
COPYING in the distribution) with the exception that you may link
|
||||
gimpmodule with the python program.
|
||||
|
||||
For more information, please see the documentation in the directory
|
||||
doc. The documentation is in SGML, and translations to text, html and
|
||||
texinfo are included in the distribution.
|
||||
|
||||
To build the program, you should be able to just type:
|
||||
./configure --prefix=<gimp-prefix>
|
||||
make
|
||||
make install
|
||||
|
||||
Pregenerated HTML docs are included with the package in the doc
|
||||
directory. If you want ps or pdf documentation, get Mark Galassi's
|
||||
docbook SGML packages.
|
||||
|
||||
Here is a list of what you will find in the subdirectories of this
|
||||
distribution:
|
||||
. - The actual source code.
|
||||
doc/ - The documentation.
|
||||
plug-ins/ - The sample plugins. Contents are copied to GIMP plug-ins
|
||||
directory.
|
||||
|
||||
|
135
plug-ins/pygimp/acinclude.m4
Normal file
135
plug-ins/pygimp/acinclude.m4
Normal file
@ -0,0 +1,135 @@
|
||||
## Find the install dirs for the python installation.
|
||||
## By James Henstridge
|
||||
|
||||
# serial 1
|
||||
|
||||
AC_DEFUN(AM_PATH_PYTHON,
|
||||
[AC_CHECK_PROGS(PYTHON, python python1.5 python1.4 python1.3,no)
|
||||
if test "$PYTHON" != no; then
|
||||
AC_MSG_CHECKING([where .py files should go])
|
||||
changequote(, )dnl
|
||||
pythondir=`$PYTHON -c '
|
||||
import sys
|
||||
if sys.version[0] > "1" or sys.version[2] > "4":
|
||||
print "%s/lib/python%s/site-packages" % (sys.prefix, sys.version[:3])
|
||||
else:
|
||||
print "%s/lib/python%s" % (sys.prefix, sys.version[:3])'`
|
||||
changequote([, ])dnl
|
||||
AC_MSG_RESULT($pythondir)
|
||||
AC_MSG_CHECKING([where python extensions should go])
|
||||
changequote(, )dnl
|
||||
pyexecdir=`$PYTHON -c '
|
||||
import sys
|
||||
if sys.version[0] > "1" or sys.version[2] > "4":
|
||||
print "%s/lib/python%s/site-packages" % (sys.exec_prefix, sys.version[:3])
|
||||
else:
|
||||
print "%s/lib/python%s/sharedmodules" % (sys.exec_prefix, sys.version[:3])'`
|
||||
changequote([, ])dnl
|
||||
AC_MSG_RESULT($pyexecdir)
|
||||
else
|
||||
# these defaults are version independent ...
|
||||
AC_MSG_CHECKING([where .py files should go])
|
||||
pythondir='$(prefix)/lib/site-python'
|
||||
AC_MSG_RESULT($pythondir)
|
||||
AC_MSG_CHECKING([where python extensions should go])
|
||||
pyexecdir='$(exec_prefix)/lib/site-python'
|
||||
AC_MSG_RESULT($pyexecdir)
|
||||
fi
|
||||
AC_SUBST(pythondir)
|
||||
AC_SUBST(pyexecdir)])
|
||||
|
||||
|
||||
## this one is commonly used with AM_PATH_PYTHONDIR ...
|
||||
dnl AM_CHECK_PYMOD(MODNAME [,SYMBOL [,ACTION-IF-FOUND [,ACTION-IF-NOT-FOUND]]])
|
||||
dnl Check if a module containing a given symbol is visible to python.
|
||||
AC_DEFUN(AM_CHECK_PYMOD,
|
||||
[AC_REQUIRE([AM_PATH_PYTHON])
|
||||
py_mod_var=`echo $1['_']$2 | sed 'y%./+-%__p_%'`
|
||||
AC_MSG_CHECKING(for ifelse([$2],[],,[$2 in ])python module $1)
|
||||
AC_CACHE_VAL(py_cv_mod_$py_mod_var, [
|
||||
ifelse([$2],[], [prog="
|
||||
import sys
|
||||
try:
|
||||
import $1
|
||||
except ImportError:
|
||||
sys.exit(1)
|
||||
except:
|
||||
sys.exit(0)
|
||||
sys.exit(0)"], [prog="
|
||||
import $1
|
||||
$1.$2"])
|
||||
if $PYTHON -c "$prog" 1>&AC_FD_CC 2>&AC_FD_CC
|
||||
then
|
||||
eval "py_cv_mod_$py_mod_var=yes"
|
||||
else
|
||||
eval "py_cv_mod_$py_mod_var=no"
|
||||
fi
|
||||
])
|
||||
py_val=`eval "echo \`echo '$py_cv_mod_'$py_mod_var\`"`
|
||||
if test "x$py_val" != xno; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$3], [],, [$3
|
||||
])dnl
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
ifelse([$4], [],, [$4
|
||||
])dnl
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
|
||||
# serial 1
|
||||
|
||||
dnl finds information needed for compilation of shared library style python
|
||||
dnl extensions. AM_PATH_PYTHON should be called before hand.
|
||||
AC_DEFUN(AM_INIT_PYEXEC_MOD,
|
||||
[AC_REQUIRE([AM_PATH_PYTHON])
|
||||
AC_MSG_CHECKING([for python headers])
|
||||
AC_CACHE_VAL(am_cv_python_includes,
|
||||
[changequote(,)dnl
|
||||
am_cv_python_includes="`$PYTHON -c '
|
||||
import sys
|
||||
includepy = \"%s/include/python%s\" % (sys.prefix, sys.version[:3])
|
||||
if sys.version[0] > \"1\" or sys.version[2] > \"4\":
|
||||
libpl = \"%s/include/python%s\" % (sys.exec_prefix, sys.version[:3])
|
||||
else:
|
||||
libpl = \"%s/lib/python%s/config\" % (sys.exec_prefix, sys.version[:3])
|
||||
print \"-I%s -I%s\" % (includepy, libpl)'`"
|
||||
changequote([, ])])
|
||||
PYTHON_INCLUDES="$am_cv_python_includes"
|
||||
AC_MSG_RESULT(found)
|
||||
AC_SUBST(PYTHON_INCLUDES)
|
||||
|
||||
AC_MSG_CHECKING([definitions from Python makefile])
|
||||
AC_CACHE_VAL(am_cv_python_makefile,
|
||||
[changequote(,)dnl
|
||||
py_makefile="`$PYTHON -c '
|
||||
import sys
|
||||
print \"%s/lib/python%s/config/Makefile\"%(sys.exec_prefix, sys.version[:3])'`"
|
||||
if test ! -f "$py_makefile"; then
|
||||
AC_MSG_ERROR([*** Couldn't find the python config makefile. Maybe you are
|
||||
*** missing the development portion of the python installation])
|
||||
fi
|
||||
eval `sed -n \
|
||||
-e "s/^CC=[ ]*\(.*\)/am_cv_python_CC='\1'/p" \
|
||||
-e "s/^OPT=[ ]*\(.*\)/am_cv_python_OPT='\1'/p" \
|
||||
-e "s/^CCSHARED=[ ]*\(.*\)/am_cv_python_CCSHARED='\1'/p" \
|
||||
-e "s/^LDSHARED=[ ]*\(.*\)/am_cv_python_LDSHARED='\1'/p" \
|
||||
-e "s/^SO=[ ]*\(.*\)/am_cv_python_SO='\1'/p" \
|
||||
$py_makefile`
|
||||
am_cv_python_makefile=found
|
||||
changequote([, ])])
|
||||
AC_MSG_RESULT(done)
|
||||
CC="$am_cv_python_CC"
|
||||
OPT="$am_cv_python_OPT"
|
||||
SO="$am_cv_python_SO"
|
||||
PYTHON_CFLAGS="$am_cv_python_CCSHARED \$(OPT)"
|
||||
PYTHON_LINK="$am_cv_python_LDSHARED -o \[$]@"
|
||||
|
||||
AC_SUBST(CC)dnl
|
||||
AC_SUBST(OPT)dnl
|
||||
AC_SUBST(SO)dnl
|
||||
AC_SUBST(PYTHON_CFLAGS)dnl
|
||||
AC_SUBST(PYTHON_LINK)])
|
||||
|
26
plug-ins/pygimp/configure.in
Normal file
26
plug-ins/pygimp/configure.in
Normal file
@ -0,0 +1,26 @@
|
||||
AC_INIT(gimpmodule.c)
|
||||
|
||||
AM_INIT_AUTOMAKE(pygimp, 0.5)
|
||||
|
||||
AM_PATH_PYTHON
|
||||
AM_INIT_PYEXEC_MOD
|
||||
|
||||
AM_CHECK_PYMOD(gtk,,,AC_MSG_ERROR([You need the pygtk package to use pygimp]))
|
||||
|
||||
AC_PATH_PROG(GIMPTOOL, gimptool, no)
|
||||
|
||||
if test "x$GIMPTOOL" = xno; then
|
||||
AC_MSG_ERROR([could not find gimptool script])
|
||||
fi
|
||||
|
||||
GIMP_CFLAGS_NOUI=`$GIMPTOOL --cflags-noui`
|
||||
GIMP_LIBS_NOUI=`$GIMPTOOL --libs-noui`
|
||||
|
||||
gimp_ver=`$GIMPTOOL --version | cut -d. -f 1-2 `
|
||||
pluginexecdir=\${libdir}/gimp/$gimp_ver/plug-ins
|
||||
|
||||
AC_SUBST(GIMP_CFLAGS_NOUI)
|
||||
AC_SUBST(GIMP_LIBS_NOUI)
|
||||
AC_SUBST(pluginexecdir)
|
||||
|
||||
AC_OUTPUT(Makefile doc/Makefile plug-ins/Makefile)
|
3
plug-ins/pygimp/doc/.cvsignore
Normal file
3
plug-ins/pygimp/doc/.cvsignore
Normal file
@ -0,0 +1,3 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
|
31
plug-ins/pygimp/doc/Makefile.am
Normal file
31
plug-ins/pygimp/doc/Makefile.am
Normal file
@ -0,0 +1,31 @@
|
||||
|
||||
noinst_DATA = pygimp.html
|
||||
|
||||
EXTRA_DIST = pygimp.sgml \
|
||||
pygimp.html \
|
||||
structure-of-plugin.html \
|
||||
procedural-database.html \
|
||||
gimp-module-procedures.html \
|
||||
gimp-objects.html \
|
||||
support-modules.html \
|
||||
end-note.html
|
||||
|
||||
printed: pygimp.ps pygimp.pdf
|
||||
|
||||
clean:
|
||||
rm -f *.html pygimp.ps pygimp.pdf
|
||||
|
||||
|
||||
pygimp.ps: pygimp.sgml
|
||||
db2ps $(srcdir)/pygimp.sgml
|
||||
|
||||
pygimp.pdf: pygimp.sgml
|
||||
db2pdf $(srcdir)/pygimp.sgml
|
||||
|
||||
pygimp.html: pygimp.sgml
|
||||
cd $(srcdir) && db2html pygimp.sgml
|
||||
cd $(srcdir) && mv pygimp/*.html .
|
||||
rm -rf $(srcdir)/pygimp
|
||||
|
||||
.PHONY: printed clean
|
||||
|
123
plug-ins/pygimp/doc/end-note.html
Normal file
123
plug-ins/pygimp/doc/end-note.html
Normal file
@ -0,0 +1,123 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//Norman Walsh//DTD DocBook HTML 1.0//EN">
|
||||
<HTML
|
||||
><HEAD
|
||||
><TITLE
|
||||
>End Note</TITLE
|
||||
><META
|
||||
NAME="GENERATOR"
|
||||
CONTENT="Modular DocBook HTML Stylesheet"><LINK
|
||||
REL="HOME"
|
||||
TITLE="Gimp Python Documentation"
|
||||
HREF="pygimp.html"><LINK
|
||||
REL="PREVIOUS"
|
||||
TITLE="Support Modules"
|
||||
HREF="support-modules.html"></HEAD
|
||||
><BODY
|
||||
><DIV
|
||||
CLASS="NAVHEADER"
|
||||
><TABLE
|
||||
WIDTH="100%"
|
||||
BORDER="0"
|
||||
CELLPADDING="0"
|
||||
CELLSPACING="0"
|
||||
><TR
|
||||
><TH
|
||||
COLSPAN="3"
|
||||
ALIGN="center"
|
||||
>Gimp Python Documentation</TH
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="10%"
|
||||
ALIGN="left"
|
||||
VALIGN="bottom"
|
||||
><A
|
||||
HREF="support-modules.html"
|
||||
>Prev</A
|
||||
></TD
|
||||
><TD
|
||||
WIDTH="80%"
|
||||
ALIGN="center"
|
||||
VALIGN="bottom"
|
||||
></TD
|
||||
><TD
|
||||
WIDTH="10%"
|
||||
ALIGN="right"
|
||||
VALIGN="bottom"
|
||||
> </TD
|
||||
></TR
|
||||
></TABLE
|
||||
><HR
|
||||
ALIGN="LEFT"
|
||||
WIDTH="100%"></DIV
|
||||
><DIV
|
||||
CLASS="SECT1"
|
||||
><H1
|
||||
CLASS="SECT1"
|
||||
><A
|
||||
NAME="END-NOTE"
|
||||
>End Note</A
|
||||
></H1
|
||||
><P
|
||||
>This package is not yet complete, but it has enough in it to
|
||||
be useful for writing plugins for Gimp. If you write any plugins
|
||||
that might be useful as examples, please mail me at <A
|
||||
HREF="mailto:james@daa.com.au"
|
||||
TARGET="_top"
|
||||
>james@daa.com.au</A
|
||||
>.</P
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="NAVFOOTER"
|
||||
><HR
|
||||
ALIGN="LEFT"
|
||||
WIDTH="100%"><TABLE
|
||||
WIDTH="100%"
|
||||
BORDER="0"
|
||||
CELLPADDING="0"
|
||||
CELLSPACING="0"
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="left"
|
||||
VALIGN="top"
|
||||
><A
|
||||
HREF="support-modules.html"
|
||||
>Prev</A
|
||||
></TD
|
||||
><TD
|
||||
WIDTH="34%"
|
||||
ALIGN="center"
|
||||
VALIGN="top"
|
||||
><A
|
||||
HREF="pygimp.html"
|
||||
>Home</A
|
||||
></TD
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="right"
|
||||
VALIGN="top"
|
||||
> </TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="left"
|
||||
VALIGN="top"
|
||||
>Support Modules</TD
|
||||
><TD
|
||||
WIDTH="34%"
|
||||
ALIGN="center"
|
||||
VALIGN="top"
|
||||
> </TD
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="right"
|
||||
VALIGN="top"
|
||||
> </TD
|
||||
></TR
|
||||
></TABLE
|
||||
></DIV
|
||||
></BODY
|
||||
></HTML
|
||||
>
|
1503
plug-ins/pygimp/doc/gimp-module-procedures.html
Normal file
1503
plug-ins/pygimp/doc/gimp-module-procedures.html
Normal file
File diff suppressed because it is too large
Load Diff
3004
plug-ins/pygimp/doc/gimp-objects.html
Normal file
3004
plug-ins/pygimp/doc/gimp-objects.html
Normal file
File diff suppressed because it is too large
Load Diff
361
plug-ins/pygimp/doc/procedural-database.html
Normal file
361
plug-ins/pygimp/doc/procedural-database.html
Normal file
@ -0,0 +1,361 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//Norman Walsh//DTD DocBook HTML 1.0//EN">
|
||||
<HTML
|
||||
><HEAD
|
||||
><TITLE
|
||||
>The Procedural Database</TITLE
|
||||
><META
|
||||
NAME="GENERATOR"
|
||||
CONTENT="Modular DocBook HTML Stylesheet"><LINK
|
||||
REL="HOME"
|
||||
TITLE="Gimp Python Documentation"
|
||||
HREF="pygimp.html"><LINK
|
||||
REL="PREVIOUS"
|
||||
TITLE="The Structure Of A Plugin"
|
||||
HREF="structure-of-plugin.html"><LINK
|
||||
REL="NEXT"
|
||||
TITLE="Gimp Module Procedures"
|
||||
HREF="gimp-module-procedures.html"></HEAD
|
||||
><BODY
|
||||
><DIV
|
||||
CLASS="NAVHEADER"
|
||||
><TABLE
|
||||
WIDTH="100%"
|
||||
BORDER="0"
|
||||
CELLPADDING="0"
|
||||
CELLSPACING="0"
|
||||
><TR
|
||||
><TH
|
||||
COLSPAN="3"
|
||||
ALIGN="center"
|
||||
>Gimp Python Documentation</TH
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="10%"
|
||||
ALIGN="left"
|
||||
VALIGN="bottom"
|
||||
><A
|
||||
HREF="structure-of-plugin.html"
|
||||
>Prev</A
|
||||
></TD
|
||||
><TD
|
||||
WIDTH="80%"
|
||||
ALIGN="center"
|
||||
VALIGN="bottom"
|
||||
></TD
|
||||
><TD
|
||||
WIDTH="10%"
|
||||
ALIGN="right"
|
||||
VALIGN="bottom"
|
||||
><A
|
||||
HREF="gimp-module-procedures.html"
|
||||
>Next</A
|
||||
></TD
|
||||
></TR
|
||||
></TABLE
|
||||
><HR
|
||||
ALIGN="LEFT"
|
||||
WIDTH="100%"></DIV
|
||||
><DIV
|
||||
CLASS="SECT1"
|
||||
><H1
|
||||
CLASS="SECT1"
|
||||
><A
|
||||
NAME="PROCEDURAL-DATABASE"
|
||||
>The Procedural Database</A
|
||||
></H1
|
||||
><P
|
||||
>The procedural database is a registry of things gimp and its
|
||||
plugins can do. When you install a procedure for your plugin, you
|
||||
are extending the procedural database.</P
|
||||
><P
|
||||
>The procedural database is self documenting, in that when
|
||||
you install a procedure in it, you also add documentation for it,
|
||||
its parameters and return values.</P
|
||||
><DIV
|
||||
CLASS="SECT2"
|
||||
><H2
|
||||
CLASS="SECT2"
|
||||
><A
|
||||
NAME="GIMP-PYTHON-MODEL"
|
||||
>The Gimp-Python Model</A
|
||||
></H2
|
||||
><P
|
||||
>In Gimp-Python, the procedural database is represented by
|
||||
the object <TT
|
||||
CLASS="PARAMETER"
|
||||
><I
|
||||
>gimp.pdb</I
|
||||
></TT
|
||||
>. In most of my
|
||||
plugins, I make an assignment from <TT
|
||||
CLASS="PARAMETER"
|
||||
><I
|
||||
>gimp.pdb</I
|
||||
></TT
|
||||
>
|
||||
to <TT
|
||||
CLASS="PARAMETER"
|
||||
><I
|
||||
>pdb</I
|
||||
></TT
|
||||
> for convenience.</P
|
||||
><P
|
||||
>You can query the procedural database with
|
||||
<TT
|
||||
CLASS="PARAMETER"
|
||||
><I
|
||||
>pdb</I
|
||||
></TT
|
||||
>'s method <TT
|
||||
CLASS="FUNCTION"
|
||||
><B
|
||||
>query</B
|
||||
></TT
|
||||
>. Its
|
||||
specification is:</P
|
||||
><TABLE
|
||||
BORDER="0"
|
||||
BGCOLOR="#E0E0E0"
|
||||
WIDTH="100%"
|
||||
><TR
|
||||
><TD
|
||||
><PRE
|
||||
CLASS="SCREEN"
|
||||
>pdb.query(name, [blurb, [help, [author, [copyright, [date, [type]]]]]])</PRE
|
||||
></TD
|
||||
></TR
|
||||
></TABLE
|
||||
><P
|
||||
>Each parameter is a regular expression that is checked
|
||||
against the corresponding field in the procedural database. The
|
||||
method returns a list of the names of matching procedures. If
|
||||
<TT
|
||||
CLASS="FUNCTION"
|
||||
><B
|
||||
>query</B
|
||||
></TT
|
||||
> is called without any arguments, it will
|
||||
return every procedure in the database.</P
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="SECT2"
|
||||
><H2
|
||||
CLASS="SECT2"
|
||||
><A
|
||||
NAME="PDB-PROCEDURES"
|
||||
>Procedural Database Procedures</A
|
||||
></H2
|
||||
><P
|
||||
>Procedures can be accessed as procedures, or by treating
|
||||
<TT
|
||||
CLASS="PARAMETER"
|
||||
><I
|
||||
>pdb</I
|
||||
></TT
|
||||
> as a mapping objest. As an example,
|
||||
the probedure <TT
|
||||
CLASS="FUNCTION"
|
||||
><B
|
||||
>gimp_edit_fill</B
|
||||
></TT
|
||||
> can be
|
||||
accessed as either <TT
|
||||
CLASS="FUNCTION"
|
||||
><B
|
||||
>pdb.gimp_edit_fill</B
|
||||
></TT
|
||||
> or
|
||||
<TT
|
||||
CLASS="FUNCTION"
|
||||
><B
|
||||
>pdb['gimp_edit_fill']</B
|
||||
></TT
|
||||
>. The second form is
|
||||
mainly for procedures whose names are not valid Python names (eg
|
||||
in script-fu-..., the dashes are interpreted as minuses).</P
|
||||
><P
|
||||
>These procedure objects have a number of attribute:</P
|
||||
><P
|
||||
></P
|
||||
><DL
|
||||
><DT
|
||||
>proc_name</DT
|
||||
><DD
|
||||
><P
|
||||
>The name of the procedure.</P
|
||||
></DD
|
||||
><DT
|
||||
>proc_blurb</DT
|
||||
><DD
|
||||
><P
|
||||
>A short peice of information about the procedure.</P
|
||||
></DD
|
||||
><DT
|
||||
>proc_help</DT
|
||||
><DD
|
||||
><P
|
||||
>More detailed information about the procedure.</P
|
||||
></DD
|
||||
><DT
|
||||
>proc_author</DT
|
||||
><DD
|
||||
><P
|
||||
>The author of the procedure.</P
|
||||
></DD
|
||||
><DT
|
||||
>proc_copyright</DT
|
||||
><DD
|
||||
><P
|
||||
>The copyright holder for the procedure (usually the
|
||||
same as the author).</P
|
||||
></DD
|
||||
><DT
|
||||
>proc_date</DT
|
||||
><DD
|
||||
><P
|
||||
>The date when the procedure was written.</P
|
||||
></DD
|
||||
><DT
|
||||
>proc_type</DT
|
||||
><DD
|
||||
><P
|
||||
>The type of procedure. This will be one of
|
||||
PROC_PLUG_IN, PROC_EXTENSION or PROC_TEMPORARY.</P
|
||||
></DD
|
||||
><DT
|
||||
>nparams</DT
|
||||
><DD
|
||||
><P
|
||||
>The number of parameters the procedure takes.</P
|
||||
></DD
|
||||
><DT
|
||||
>nreturn_vals</DT
|
||||
><DD
|
||||
><P
|
||||
>The number of return values the procedure gives.</P
|
||||
></DD
|
||||
><DT
|
||||
>params</DT
|
||||
><DD
|
||||
><P
|
||||
>A description of parameters of the procedure. It
|
||||
takes the form of a tuple of 3-tuples, where each 3-tuple
|
||||
describes a parameter. The items in the 3-tuple are a
|
||||
parameter type (one of the PARAM_* constants), a
|
||||
name for the parameter, and a description of the
|
||||
parameter.</P
|
||||
></DD
|
||||
><DT
|
||||
>return_vals</DT
|
||||
><DD
|
||||
><P
|
||||
>A description of the return values. It takes the
|
||||
same form as the <TT
|
||||
CLASS="LITERAL"
|
||||
>params</TT
|
||||
>
|
||||
attribute.</P
|
||||
></DD
|
||||
></DL
|
||||
><P
|
||||
>A procedure object may also be called. At this point,
|
||||
Gimp-Python doesn't support keyword arguments for PDB
|
||||
procedures. Arguments are passed to the procedure in the normal
|
||||
method. The return depends on the number of return values:</P
|
||||
><P
|
||||
></P
|
||||
><UL
|
||||
><LI
|
||||
><P
|
||||
>If there are zero return values,
|
||||
<TT
|
||||
CLASS="LITERAL"
|
||||
>None</TT
|
||||
> is returned.</P
|
||||
></LI
|
||||
><LI
|
||||
><P
|
||||
>If there is only a single return value, it is
|
||||
returned.</P
|
||||
></LI
|
||||
><LI
|
||||
><P
|
||||
>If there are more return values, then they are
|
||||
returned as a tuple.</P
|
||||
></LI
|
||||
></UL
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="SECT2"
|
||||
><H2
|
||||
CLASS="SECT2"
|
||||
><A
|
||||
NAME="MORE-INFORMATION"
|
||||
>More Information</A
|
||||
></H2
|
||||
><P
|
||||
>For more information on invoking PDB procedures, please
|
||||
see the example plugins. For information on individual
|
||||
procedures, please see the PDB Browser plugin (in the Xtns
|
||||
menu). It alows you to peruse to the database
|
||||
interactively.</P
|
||||
></DIV
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="NAVFOOTER"
|
||||
><HR
|
||||
ALIGN="LEFT"
|
||||
WIDTH="100%"><TABLE
|
||||
WIDTH="100%"
|
||||
BORDER="0"
|
||||
CELLPADDING="0"
|
||||
CELLSPACING="0"
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="left"
|
||||
VALIGN="top"
|
||||
><A
|
||||
HREF="structure-of-plugin.html"
|
||||
>Prev</A
|
||||
></TD
|
||||
><TD
|
||||
WIDTH="34%"
|
||||
ALIGN="center"
|
||||
VALIGN="top"
|
||||
><A
|
||||
HREF="pygimp.html"
|
||||
>Home</A
|
||||
></TD
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="right"
|
||||
VALIGN="top"
|
||||
><A
|
||||
HREF="gimp-module-procedures.html"
|
||||
>Next</A
|
||||
></TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="left"
|
||||
VALIGN="top"
|
||||
>The Structure Of A Plugin</TD
|
||||
><TD
|
||||
WIDTH="34%"
|
||||
ALIGN="center"
|
||||
VALIGN="top"
|
||||
> </TD
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="right"
|
||||
VALIGN="top"
|
||||
>Gimp Module Procedures</TD
|
||||
></TR
|
||||
></TABLE
|
||||
></DIV
|
||||
></BODY
|
||||
></HTML
|
||||
>
|
232
plug-ins/pygimp/doc/pygimp.html
Normal file
232
plug-ins/pygimp/doc/pygimp.html
Normal file
@ -0,0 +1,232 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//Norman Walsh//DTD DocBook HTML 1.0//EN">
|
||||
<HTML
|
||||
><HEAD
|
||||
><TITLE
|
||||
>Gimp Python Documentation</TITLE
|
||||
><META
|
||||
NAME="GENERATOR"
|
||||
CONTENT="Modular DocBook HTML Stylesheet"><LINK
|
||||
REL="NEXT"
|
||||
TITLE="The Structure Of A Plugin"
|
||||
HREF="structure-of-plugin.html"></HEAD
|
||||
><BODY
|
||||
><DIV
|
||||
CLASS="ARTICLE"
|
||||
><DIV
|
||||
CLASS="TITLEPAGE"
|
||||
><H1
|
||||
CLASS="TITLE"
|
||||
>Gimp Python Documentation</H1
|
||||
><P
|
||||
CLASS="AUTHOR"
|
||||
><I
|
||||
>James Henstridge</I
|
||||
></P
|
||||
><DIV
|
||||
CLASS="AFFILIATION"
|
||||
><P
|
||||
CLASS="LITERALLAYOUT"
|
||||
> <TT
|
||||
CLASS="EMAIL"
|
||||
><<A
|
||||
HREF="mailto:james@daa.com.au"
|
||||
>james@daa.com.au</A
|
||||
>></TT
|
||||
><br>
|
||||
</P
|
||||
></DIV
|
||||
><P
|
||||
>Published <SPAN
|
||||
CLASS="PUBDATE"
|
||||
>v0.4, 5 July 1999</SPAN
|
||||
></P
|
||||
><DIV
|
||||
CLASS="ABSTRACT"
|
||||
><P
|
||||
>This document outlines the interfaces to Gimp-Python,
|
||||
which is a set of Python modules that act as a wrapper to
|
||||
<TT
|
||||
CLASS="FILENAME"
|
||||
>libgimp</TT
|
||||
> allowing the writing of
|
||||
plug-ins for Gimp. In this way, Gimp-Python is similar to
|
||||
Script-Fu, except that you can use the full set of Python
|
||||
extension modules from the plug-in.</P
|
||||
></DIV
|
||||
><HR></DIV
|
||||
><DIV
|
||||
CLASS="TOC"
|
||||
><DL
|
||||
><DT
|
||||
><B
|
||||
>Table of Contents</B
|
||||
></DT
|
||||
><DT
|
||||
><A
|
||||
HREF="pygimp.html#INTRODUCTION"
|
||||
>Introduction</A
|
||||
></DT
|
||||
><DT
|
||||
><A
|
||||
HREF="structure-of-plugin.html"
|
||||
>The Structure Of A Plugin</A
|
||||
></DT
|
||||
><DT
|
||||
><A
|
||||
HREF="procedural-database.html"
|
||||
>The Procedural Database</A
|
||||
></DT
|
||||
><DT
|
||||
><A
|
||||
HREF="gimp-module-procedures.html"
|
||||
>Gimp Module Procedures</A
|
||||
></DT
|
||||
><DT
|
||||
><A
|
||||
HREF="gimp-objects.html"
|
||||
>Gimp Objects</A
|
||||
></DT
|
||||
><DT
|
||||
><A
|
||||
HREF="support-modules.html"
|
||||
>Support Modules</A
|
||||
></DT
|
||||
><DT
|
||||
><A
|
||||
HREF="end-note.html"
|
||||
>End Note</A
|
||||
></DT
|
||||
></DL
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="SECT1"
|
||||
><H1
|
||||
CLASS="SECT1"
|
||||
><A
|
||||
NAME="INTRODUCTION"
|
||||
>Introduction</A
|
||||
></H1
|
||||
><DIV
|
||||
CLASS="SECT2"
|
||||
><H2
|
||||
CLASS="SECT2"
|
||||
><A
|
||||
NAME="WHAT-IS-IT"
|
||||
>What is it?</A
|
||||
></H2
|
||||
><P
|
||||
>Gimp-Python is a scripting extension for Gimp, similar to
|
||||
Script-Fu. The main difference is in what is called first. In
|
||||
Script-Fu, the script-fu plugin executes the script, while in
|
||||
Gimp-Python the script is in control.</P
|
||||
><P
|
||||
>In fact, you will find that the Gimp-Python scripts start
|
||||
with the line <TT
|
||||
CLASS="LITERAL"
|
||||
>#!/usr/bin/python</TT
|
||||
>. The
|
||||
gimp extension is loaded with the familiar
|
||||
<TT
|
||||
CLASS="LITERAL"
|
||||
>import</TT
|
||||
> command.</P
|
||||
><P
|
||||
>Another point of difference between Gimp-Python and
|
||||
Script-Fu is that Gimp-Python stores images, layers, channels
|
||||
and other types as objects rather than just storing their ID.
|
||||
This allows better type checking that is missing from Script-Fu,
|
||||
and allows those types to act as objects, complete with
|
||||
attributes and methods.</P
|
||||
><P
|
||||
>Also, Gimp-Python is not limited to just calling
|
||||
procedures from the PDB. It also implements the rest of
|
||||
<TT
|
||||
CLASS="FILENAME"
|
||||
>libgimp</TT
|
||||
>, including tiles and pixel regions,
|
||||
and access to other lower level functions.</P
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="SECT2"
|
||||
><H2
|
||||
CLASS="SECT2"
|
||||
><A
|
||||
NAME="INSTALLATION"
|
||||
>Installation</A
|
||||
></H2
|
||||
><P
|
||||
>Gimp-python consists of a Python module written in C and
|
||||
some native python support modules. You can build pygimp with
|
||||
the commands:</P
|
||||
><TABLE
|
||||
BORDER="0"
|
||||
BGCOLOR="#E0E0E0"
|
||||
WIDTH="100%"
|
||||
><TR
|
||||
><TD
|
||||
><PRE
|
||||
CLASS="PROGRAMLISTING"
|
||||
>./configure
|
||||
make
|
||||
make install</PRE
|
||||
></TD
|
||||
></TR
|
||||
></TABLE
|
||||
><P
|
||||
>This will build and install gimpmodule and its supporting
|
||||
modules, and install the sample plugins in gimp's plugin
|
||||
directory.</P
|
||||
></DIV
|
||||
></DIV
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="NAVFOOTER"
|
||||
><HR
|
||||
ALIGN="LEFT"
|
||||
WIDTH="100%"><TABLE
|
||||
WIDTH="100%"
|
||||
BORDER="0"
|
||||
CELLPADDING="0"
|
||||
CELLSPACING="0"
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="left"
|
||||
VALIGN="top"
|
||||
> </TD
|
||||
><TD
|
||||
WIDTH="34%"
|
||||
ALIGN="center"
|
||||
VALIGN="top"
|
||||
> </TD
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="right"
|
||||
VALIGN="top"
|
||||
><A
|
||||
HREF="structure-of-plugin.html"
|
||||
>Next</A
|
||||
></TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="left"
|
||||
VALIGN="top"
|
||||
> </TD
|
||||
><TD
|
||||
WIDTH="34%"
|
||||
ALIGN="center"
|
||||
VALIGN="top"
|
||||
> </TD
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="right"
|
||||
VALIGN="top"
|
||||
>The Structure Of A Plugin</TD
|
||||
></TR
|
||||
></TABLE
|
||||
></DIV
|
||||
></BODY
|
||||
></HTML
|
||||
>
|
2101
plug-ins/pygimp/doc/pygimp.sgml
Normal file
2101
plug-ins/pygimp/doc/pygimp.sgml
Normal file
File diff suppressed because it is too large
Load Diff
573
plug-ins/pygimp/doc/structure-of-plugin.html
Normal file
573
plug-ins/pygimp/doc/structure-of-plugin.html
Normal file
@ -0,0 +1,573 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//Norman Walsh//DTD DocBook HTML 1.0//EN">
|
||||
<HTML
|
||||
><HEAD
|
||||
><TITLE
|
||||
>The Structure Of A Plugin</TITLE
|
||||
><META
|
||||
NAME="GENERATOR"
|
||||
CONTENT="Modular DocBook HTML Stylesheet"><LINK
|
||||
REL="HOME"
|
||||
TITLE="Gimp Python Documentation"
|
||||
HREF="pygimp.html"><LINK
|
||||
REL="PREVIOUS"
|
||||
TITLE="Gimp Python Documentation"
|
||||
HREF="pygimp.html"><LINK
|
||||
REL="NEXT"
|
||||
TITLE="The Procedural Database"
|
||||
HREF="procedural-database.html"></HEAD
|
||||
><BODY
|
||||
><DIV
|
||||
CLASS="NAVHEADER"
|
||||
><TABLE
|
||||
WIDTH="100%"
|
||||
BORDER="0"
|
||||
CELLPADDING="0"
|
||||
CELLSPACING="0"
|
||||
><TR
|
||||
><TH
|
||||
COLSPAN="3"
|
||||
ALIGN="center"
|
||||
>Gimp Python Documentation</TH
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="10%"
|
||||
ALIGN="left"
|
||||
VALIGN="bottom"
|
||||
><A
|
||||
HREF="pygimp.html"
|
||||
>Prev</A
|
||||
></TD
|
||||
><TD
|
||||
WIDTH="80%"
|
||||
ALIGN="center"
|
||||
VALIGN="bottom"
|
||||
></TD
|
||||
><TD
|
||||
WIDTH="10%"
|
||||
ALIGN="right"
|
||||
VALIGN="bottom"
|
||||
><A
|
||||
HREF="procedural-database.html"
|
||||
>Next</A
|
||||
></TD
|
||||
></TR
|
||||
></TABLE
|
||||
><HR
|
||||
ALIGN="LEFT"
|
||||
WIDTH="100%"></DIV
|
||||
><DIV
|
||||
CLASS="SECT1"
|
||||
><H1
|
||||
CLASS="SECT1"
|
||||
><A
|
||||
NAME="STRUCTURE-OF-PLUGIN"
|
||||
>The Structure Of A Plugin</A
|
||||
></H1
|
||||
><P
|
||||
>The majority of code in this package resides in
|
||||
<TT
|
||||
CLASS="FILENAME"
|
||||
>gimpmodule.c</TT
|
||||
>, but this provides a poor
|
||||
interface for implementing some portions of a plugin. For this
|
||||
reason, there is a python module called
|
||||
<TT
|
||||
CLASS="FILENAME"
|
||||
>plugin.py</TT
|
||||
> that sets out a structure for
|
||||
plugins and implements some things that were either too dificult
|
||||
or impossible to do in C.</P
|
||||
><P
|
||||
>The main purpose of <TT
|
||||
CLASS="FILENAME"
|
||||
>plugin.py</TT
|
||||
> was to
|
||||
implement an object oriented structure for plug-ins. As well as
|
||||
this, it handles tracebacks, which are otherwise ignored by
|
||||
<TT
|
||||
CLASS="FILENAME"
|
||||
>libgimp</TT
|
||||
>, and gives a method to call
|
||||
other Gimp-Python plug-ins without going through the procedural
|
||||
database.</P
|
||||
><DIV
|
||||
CLASS="SECT2"
|
||||
><H2
|
||||
CLASS="SECT2"
|
||||
><A
|
||||
NAME="EXAMPLE-PLUGIN"
|
||||
>An Example Plugin</A
|
||||
></H2
|
||||
><P
|
||||
>As in a lot of manuals, the first thing you examine is an
|
||||
example, so here is an example. I have included it before
|
||||
explaining what it does to allow more advanced programmers to
|
||||
see the structure up front. It is a translation of the clothify
|
||||
Script-Fu extension:</P
|
||||
><DIV
|
||||
CLASS="EXAMPLE"
|
||||
><P
|
||||
><B
|
||||
>Example 1. A sample python plugin</B
|
||||
></P
|
||||
><TABLE
|
||||
BORDER="0"
|
||||
BGCOLOR="#E0E0E0"
|
||||
WIDTH="100%"
|
||||
><TR
|
||||
><TD
|
||||
><PRE
|
||||
CLASS="PROGRAMLISTING"
|
||||
>#!/usr/bin/python
|
||||
import math
|
||||
from gimpfu import *
|
||||
|
||||
have_gimp11 = gimp.major_version > 1 or \
|
||||
gimp.major_version == 1 and gimp.minor_version >= 1
|
||||
|
||||
def python_clothify(timg, tdrawable, bx=9, by=9,
|
||||
azimuth=135, elevation=45, depth=3):
|
||||
bx = 9 ; by = 9 ; azimuth = 135 ; elevation = 45 ; depth = 3
|
||||
width = tdrawable.width
|
||||
height = tdrawable.height
|
||||
img = gimp.image(width, height, RGB)
|
||||
layer_one = gimp.layer(img, "X Dots", width, height, RGB_IMAGE,
|
||||
100, NORMAL_MODE)
|
||||
img.disable_undo()
|
||||
if have_gimp11:
|
||||
pdb.gimp_edit_fill(layer_one)
|
||||
else:
|
||||
pdb.gimp_edit_fill(img, layer_one)
|
||||
img.add_layer(layer_one, 0)
|
||||
pdb.plug_in_noisify(img, layer_one, 0, 0.7, 0.7, 0.7, 0.7)
|
||||
layer_two = layer_one.copy()
|
||||
layer_two.mode = MULTIPLY_MODE
|
||||
layer_two.name = "Y Dots"
|
||||
img.add_layer(layer_two, 0)
|
||||
pdb.plug_in_gauss_rle(img, layer_one, bx, 1, 0)
|
||||
pdb.plug_in_gauss_rle(img, layer_two, by, 0, 1)
|
||||
img.flatten()
|
||||
bump_layer = img.active_layer
|
||||
pdb.plug_in_c_astretch(img, bump_layer)
|
||||
pdb.plug_in_noisify(img, bump_layer, 0, 0.2, 0.2, 0.2, 0.2)
|
||||
pdb.plug_in_bump_map(img, tdrawable, bump_layer, azimuth,
|
||||
elevation, depth, 0, 0, 0, 0, TRUE, FALSE, 0)
|
||||
gimp.delete(img)
|
||||
|
||||
register(
|
||||
"python_fu_clothify",
|
||||
"Make the specified layer look like it is printed on cloth",
|
||||
"Make the specified layer look like it is printed on cloth",
|
||||
"James Henstridge",
|
||||
"James Henstridge",
|
||||
"1997-1999",
|
||||
"<Image>/Python-Fu/Alchemy/Clothify",
|
||||
"RGB*, GRAY*",
|
||||
[
|
||||
(PF_INT, "x_blur", "X Blur", 9),
|
||||
(PF_INT, "y_blur", "Y Blur", 9),
|
||||
(PF_INT, "azimuth", "Azimuth", 135),
|
||||
(PF_INT, "elevation", "elevation", 45),
|
||||
(PF_INT, "depth", "Depth", 3)
|
||||
],
|
||||
[],
|
||||
python_clothify)
|
||||
|
||||
main()</PRE
|
||||
></TD
|
||||
></TR
|
||||
></TABLE
|
||||
></DIV
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="SECT2"
|
||||
><H2
|
||||
CLASS="SECT2"
|
||||
><A
|
||||
NAME="IMPORTANT-MODULES"
|
||||
>Import Modules</A
|
||||
></H2
|
||||
><P
|
||||
>In this plugin, a number of modules are imported. The
|
||||
important ones are:</P
|
||||
><P
|
||||
></P
|
||||
><UL
|
||||
><LI
|
||||
><P
|
||||
><TT
|
||||
CLASS="FILENAME"
|
||||
>gimpfu</TT
|
||||
>: this module provides a
|
||||
simple interface for writing plugins, similar to what
|
||||
script-fu provides. It provides the GUI for entering in
|
||||
parameters in interactive mode and performs some sanity
|
||||
checks when registering the plugin.</P
|
||||
><P
|
||||
>By using "from gimpfu import *", this module also
|
||||
provides an easy way to get all the commonly used symbols
|
||||
into the plugin's namespace.</P
|
||||
></LI
|
||||
><LI
|
||||
><P
|
||||
><TT
|
||||
CLASS="FILENAME"
|
||||
>gimp</TT
|
||||
>: the main part of the gimp
|
||||
extension. This is imported with gimpfu.</P
|
||||
></LI
|
||||
><LI
|
||||
><P
|
||||
><TT
|
||||
CLASS="FILENAME"
|
||||
>gimpenums</TT
|
||||
>: a number of useful
|
||||
constants. This is also automatically imported with
|
||||
gimpfu.</P
|
||||
></LI
|
||||
></UL
|
||||
><P
|
||||
>The pdb variable is a variable for accessing the
|
||||
procedural database. It is imported into the plugin's namespace
|
||||
with gimpfu for convenience.</P
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="SECT2"
|
||||
><H2
|
||||
CLASS="SECT2"
|
||||
><A
|
||||
NAME="PLUGIN-FRAMEWORK"
|
||||
>Plugin Framework</A
|
||||
></H2
|
||||
><P
|
||||
>With pygimp-0.4, the gimpfu module was introduced. It
|
||||
simplifies writing plugins a lot. It handles the run mode
|
||||
(interactive, non interactive or run with last values),
|
||||
providing a GUI for interactive mode and saving the last used
|
||||
settings.</P
|
||||
><P
|
||||
>Using the gimpfu plugin, all you need to do is write the
|
||||
function that should be run, make a call to
|
||||
<TT
|
||||
CLASS="FUNCTION"
|
||||
><B
|
||||
>register</B
|
||||
></TT
|
||||
>, and finally a call to
|
||||
<TT
|
||||
CLASS="FUNCTION"
|
||||
><B
|
||||
>main</B
|
||||
></TT
|
||||
> to get the plugin started.</P
|
||||
><P
|
||||
>If the plugin is to be run on an image, the first
|
||||
parameter to the plugin function should be the image, and the
|
||||
second should be the current drawable (do not worry about the
|
||||
run_mode parameter). Plugins that do not act on an existing
|
||||
image (and hence go in the toolbox's menus) do not need these
|
||||
parameters. Any other parameters are specific to the
|
||||
plugin.</P
|
||||
><P
|
||||
>After defining the plugin function, you need to call
|
||||
<TT
|
||||
CLASS="FUNCTION"
|
||||
><B
|
||||
>register</B
|
||||
></TT
|
||||
> to register the plugin with gimp
|
||||
(When the plugin is run to query it, this information is passed
|
||||
to gimp. When it is run interactively, this information is used
|
||||
to construct the GUI). The parameters to
|
||||
<TT
|
||||
CLASS="FUNCTION"
|
||||
><B
|
||||
>register</B
|
||||
></TT
|
||||
> are:</P
|
||||
><P
|
||||
></P
|
||||
><TABLE
|
||||
BORDER="0"
|
||||
><TR
|
||||
><TD
|
||||
>name</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>blurb</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>help</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>author</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>copyright</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>date</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>menupath</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>imagetypes</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>params</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>results</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>function</TD
|
||||
></TR
|
||||
></TABLE
|
||||
><P
|
||||
></P
|
||||
><P
|
||||
>Most of these parameters are quite self explanatory. The
|
||||
menupath option should start with <Image%gt;/ for image
|
||||
plugins and <Toolbox>/ for toolbox plugins. The remainder
|
||||
of the menupath is a slash separated path to its menu item.</P
|
||||
><P
|
||||
>The params parameter holds a list parameters for the
|
||||
function. It is a list of tuples. Note that you do not have to
|
||||
specify the run_type, image or drawable parameters, as gimpfu
|
||||
will add these automatically for you. The tuple format is
|
||||
(type, name, description, default [, extra]). The allowed type
|
||||
codes are:</P
|
||||
><P
|
||||
></P
|
||||
><TABLE
|
||||
BORDER="0"
|
||||
><TR
|
||||
><TD
|
||||
>PF_INT8</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_INT16</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_INT32</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_INT</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_FLOAT</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_STRING</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_VALUE</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_INT8ARRAY</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_INT16ARRAY</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_INT32ARRAY</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_INTARRAY</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_FLOATARRAY</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_STRINGARRAY</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_COLOR</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_COLOUR</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_REGION</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_IMAGE</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_LAYER</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_CHANNEL</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_DRAWABLE</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_TOGGLE</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_BOOL</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_SLIDER</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_SPINNER</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_ADJUSTMENT</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_FONT</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_FILE</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_BRUSH</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_PATTERN</TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
>PF_GRADIENT</TD
|
||||
></TR
|
||||
></TABLE
|
||||
><P
|
||||
></P
|
||||
><P
|
||||
>These values map onto the standard PARAM_* constants. The
|
||||
reason to use the extra constants is that they give gimpfu more
|
||||
information, so it can produce a better interface (for instance,
|
||||
the PF_FONT type is equivalent to PARAM_STRING, but in the GUI
|
||||
you get a small button that will bring up a font selection
|
||||
dialog).</P
|
||||
><P
|
||||
>The PF_SLIDER, PF_SPINNER and PF_ADJUSTMENT types require
|
||||
the extra parameter. It is of the form (min, max, step), and
|
||||
gives the limits for the spin button or slider.</P
|
||||
><P
|
||||
>The results parameter is a list of 3-tuples of the form
|
||||
(type, name, description). It defines the return values for the
|
||||
function. If there is only a single return value, the plugin
|
||||
function should return just that value. If there is more than
|
||||
one, the plugin function should return a tuple of results.</P
|
||||
><P
|
||||
>The final parameter to <TT
|
||||
CLASS="FUNCTION"
|
||||
><B
|
||||
>register</B
|
||||
></TT
|
||||
> is
|
||||
the plugin function itself.</P
|
||||
><P
|
||||
>After registering one or more plugin functions, you must
|
||||
call the <TT
|
||||
CLASS="FUNCTION"
|
||||
><B
|
||||
>main</B
|
||||
></TT
|
||||
> function. This will cause
|
||||
the plugin to start running. A GUI will be displayed when
|
||||
needed, and your plugin function will be called at the
|
||||
appropriate times.</P
|
||||
></DIV
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="NAVFOOTER"
|
||||
><HR
|
||||
ALIGN="LEFT"
|
||||
WIDTH="100%"><TABLE
|
||||
WIDTH="100%"
|
||||
BORDER="0"
|
||||
CELLPADDING="0"
|
||||
CELLSPACING="0"
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="left"
|
||||
VALIGN="top"
|
||||
><A
|
||||
HREF="pygimp.html"
|
||||
>Prev</A
|
||||
></TD
|
||||
><TD
|
||||
WIDTH="34%"
|
||||
ALIGN="center"
|
||||
VALIGN="top"
|
||||
><A
|
||||
HREF="pygimp.html"
|
||||
>Home</A
|
||||
></TD
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="right"
|
||||
VALIGN="top"
|
||||
><A
|
||||
HREF="procedural-database.html"
|
||||
>Next</A
|
||||
></TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="left"
|
||||
VALIGN="top"
|
||||
>Gimp Python Documentation</TD
|
||||
><TD
|
||||
WIDTH="34%"
|
||||
ALIGN="center"
|
||||
VALIGN="top"
|
||||
> </TD
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="right"
|
||||
VALIGN="top"
|
||||
>The Procedural Database</TD
|
||||
></TR
|
||||
></TABLE
|
||||
></DIV
|
||||
></BODY
|
||||
></HTML
|
||||
>
|
259
plug-ins/pygimp/doc/support-modules.html
Normal file
259
plug-ins/pygimp/doc/support-modules.html
Normal file
@ -0,0 +1,259 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//Norman Walsh//DTD DocBook HTML 1.0//EN">
|
||||
<HTML
|
||||
><HEAD
|
||||
><TITLE
|
||||
>Support Modules</TITLE
|
||||
><META
|
||||
NAME="GENERATOR"
|
||||
CONTENT="Modular DocBook HTML Stylesheet"><LINK
|
||||
REL="HOME"
|
||||
TITLE="Gimp Python Documentation"
|
||||
HREF="pygimp.html"><LINK
|
||||
REL="PREVIOUS"
|
||||
TITLE="Gimp Objects"
|
||||
HREF="gimp-objects.html"><LINK
|
||||
REL="NEXT"
|
||||
TITLE="End Note"
|
||||
HREF="end-note.html"></HEAD
|
||||
><BODY
|
||||
><DIV
|
||||
CLASS="NAVHEADER"
|
||||
><TABLE
|
||||
WIDTH="100%"
|
||||
BORDER="0"
|
||||
CELLPADDING="0"
|
||||
CELLSPACING="0"
|
||||
><TR
|
||||
><TH
|
||||
COLSPAN="3"
|
||||
ALIGN="center"
|
||||
>Gimp Python Documentation</TH
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="10%"
|
||||
ALIGN="left"
|
||||
VALIGN="bottom"
|
||||
><A
|
||||
HREF="gimp-objects.html"
|
||||
>Prev</A
|
||||
></TD
|
||||
><TD
|
||||
WIDTH="80%"
|
||||
ALIGN="center"
|
||||
VALIGN="bottom"
|
||||
></TD
|
||||
><TD
|
||||
WIDTH="10%"
|
||||
ALIGN="right"
|
||||
VALIGN="bottom"
|
||||
><A
|
||||
HREF="end-note.html"
|
||||
>Next</A
|
||||
></TD
|
||||
></TR
|
||||
></TABLE
|
||||
><HR
|
||||
ALIGN="LEFT"
|
||||
WIDTH="100%"></DIV
|
||||
><DIV
|
||||
CLASS="SECT1"
|
||||
><H1
|
||||
CLASS="SECT1"
|
||||
><A
|
||||
NAME="SUPPORT-MODULES"
|
||||
>Support Modules</A
|
||||
></H1
|
||||
><P
|
||||
>This section describes the modules that help make using the
|
||||
<TT
|
||||
CLASS="FILENAME"
|
||||
>gimp</TT
|
||||
> module easier. These range from a set
|
||||
of constants to storing persistent data.</P
|
||||
><DIV
|
||||
CLASS="SECT2"
|
||||
><H2
|
||||
CLASS="SECT2"
|
||||
><A
|
||||
NAME="GIMPENUMS-MODULE"
|
||||
>The gimpenums Module</A
|
||||
></H2
|
||||
><P
|
||||
>This module contains all the constants found in the header
|
||||
<TT
|
||||
CLASS="FILENAME"
|
||||
>libgimp/gimpenums.h</TT
|
||||
>, as well as some extra
|
||||
constants that are available in Script-Fu.</P
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="SECT2"
|
||||
><H2
|
||||
CLASS="SECT2"
|
||||
><A
|
||||
NAME="AEN1466"
|
||||
>The gimpfu Module</A
|
||||
></H2
|
||||
><P
|
||||
>This module was fully described in an earlier section. It
|
||||
provides an easy interface for writing plugins, where you do not
|
||||
need to worry about run_modes, GUI's and saving previous values.
|
||||
It is the recommended module for writing plugins.</P
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="SECT2"
|
||||
><H2
|
||||
CLASS="SECT2"
|
||||
><A
|
||||
NAME="GIMPPLUGIN-MODULE"
|
||||
>The gimpplugin Module</A
|
||||
></H2
|
||||
><P
|
||||
>This module provides the framework for writing Gimp
|
||||
plugins in Python. It gives more flexibility for writing
|
||||
plugins than the gimpfu module, but does not offer as many
|
||||
features (such as automatic GUI building).</P
|
||||
><P
|
||||
>To use this framework you subclass
|
||||
<TT
|
||||
CLASS="FUNCTION"
|
||||
><B
|
||||
>gimpplugin.plugin</B
|
||||
></TT
|
||||
> like so:</P
|
||||
><TABLE
|
||||
BORDER="0"
|
||||
BGCOLOR="#E0E0E0"
|
||||
WIDTH="100%"
|
||||
><TR
|
||||
><TD
|
||||
><PRE
|
||||
CLASS="PROGRAMLISTING"
|
||||
>import gimpplugin
|
||||
class myplugin(gimpplugin.plugin):
|
||||
def init(self):
|
||||
# initialisation routines
|
||||
# called when gimp starts.
|
||||
def quit(self):
|
||||
# clean up routines
|
||||
# called when gimp exits (normally).
|
||||
def query(self):
|
||||
# called to find what functionality the plugin provides.
|
||||
gimp.install_procedure("procname", ...)
|
||||
# note that this method name matches the first arg of
|
||||
# gimp.install_procedure
|
||||
def procname(self, arg1, ...):
|
||||
# do what ever this plugin should do</PRE
|
||||
></TD
|
||||
></TR
|
||||
></TABLE
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="SECT2"
|
||||
><H2
|
||||
CLASS="SECT2"
|
||||
><A
|
||||
NAME="GIMPSHELF-MODULE"
|
||||
>The gimpshelf Module</A
|
||||
></H2
|
||||
><P
|
||||
>This module gives a nicer interface to the persistent
|
||||
storage interface for Gimp plugins. Due to the complicated
|
||||
nature of Python objects (there is often a lot of connections
|
||||
between them), it can be dificult to work out what to store in
|
||||
gimp's persistent storage. The python interface only allows
|
||||
storage of strings, so this module wraps pickle and unpickle to
|
||||
allow persistentstorage of any python object.</P
|
||||
><P
|
||||
>Here is some examples of using this module:</P
|
||||
><TABLE
|
||||
BORDER="0"
|
||||
BGCOLOR="#E0E0E0"
|
||||
WIDTH="100%"
|
||||
><TR
|
||||
><TD
|
||||
><PRE
|
||||
CLASS="SCREEN"
|
||||
>>>> from gimpshelf import shelf
|
||||
>>> shelf['james'] = ['forty-two', (42, 42L, 42.0)]
|
||||
>>> shelf.has_key('james')
|
||||
1
|
||||
>>> shelf['james']
|
||||
['forty-two', (42, 42L, 42.0)]</PRE
|
||||
></TD
|
||||
></TR
|
||||
></TABLE
|
||||
><P
|
||||
>Anything you store with
|
||||
<TT
|
||||
CLASS="FUNCTION"
|
||||
><B
|
||||
>gimpshelf.shelf</B
|
||||
></TT
|
||||
> will exist until Gimp
|
||||
exits. This makes this interface perfect for when a plugin is
|
||||
executed with the run mode
|
||||
<TT
|
||||
CLASS="LITERAL"
|
||||
>RUN_WITH_LAST_VALS</TT
|
||||
>.</P
|
||||
></DIV
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="NAVFOOTER"
|
||||
><HR
|
||||
ALIGN="LEFT"
|
||||
WIDTH="100%"><TABLE
|
||||
WIDTH="100%"
|
||||
BORDER="0"
|
||||
CELLPADDING="0"
|
||||
CELLSPACING="0"
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="left"
|
||||
VALIGN="top"
|
||||
><A
|
||||
HREF="gimp-objects.html"
|
||||
>Prev</A
|
||||
></TD
|
||||
><TD
|
||||
WIDTH="34%"
|
||||
ALIGN="center"
|
||||
VALIGN="top"
|
||||
><A
|
||||
HREF="pygimp.html"
|
||||
>Home</A
|
||||
></TD
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="right"
|
||||
VALIGN="top"
|
||||
><A
|
||||
HREF="end-note.html"
|
||||
>Next</A
|
||||
></TD
|
||||
></TR
|
||||
><TR
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="left"
|
||||
VALIGN="top"
|
||||
>Gimp Objects</TD
|
||||
><TD
|
||||
WIDTH="34%"
|
||||
ALIGN="center"
|
||||
VALIGN="top"
|
||||
> </TD
|
||||
><TD
|
||||
WIDTH="33%"
|
||||
ALIGN="right"
|
||||
VALIGN="top"
|
||||
>End Note</TD
|
||||
></TR
|
||||
></TABLE
|
||||
></DIV
|
||||
></BODY
|
||||
></HTML
|
||||
>
|
185
plug-ins/pygimp/gimpenums.py
Normal file
185
plug-ins/pygimp/gimpenums.py
Normal file
@ -0,0 +1,185 @@
|
||||
# Gimp-Python - allows the writing of Gimp plugins in Python.
|
||||
# Copyright (C) 1997 James Henstridge <james@daa.com.au>
|
||||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
# gimpenums.py -- constants for use with the gimp module
|
||||
#
|
||||
# this file contains constants that are useful for use in
|
||||
# gimp plugins. Just add 'from gimpenums import *' to the top
|
||||
# of the script
|
||||
|
||||
RGB = 0
|
||||
GRAY = 1
|
||||
INDEXED = 2
|
||||
|
||||
RGB_IMAGE = 0
|
||||
RGBA_IMAGE = 1
|
||||
GRAY_IMAGE = 2
|
||||
GRAYA_IMAGE = 3
|
||||
INDEXED_IMAGE = 4
|
||||
INDEXEDA_IMAGE = 5
|
||||
|
||||
NORMAL_MODE = 0
|
||||
DISSOLVE_MODE = 1
|
||||
MULTIPLY_MODE = 3
|
||||
SCREEN_MODE = 4
|
||||
OVERLAY_MODE = 5
|
||||
DIFFERENCE_MODE = 6
|
||||
ADDITION_MODE = 7
|
||||
SUBTACT_MODE = 8
|
||||
DARKEN_ONLY_MODE = 9
|
||||
LIGHTEN_ONLY_MODE = 10
|
||||
HUE_MODE = 11
|
||||
SATURATION_MODE = 12
|
||||
COLOR_MODE = 13
|
||||
VALUE_MODE = 14
|
||||
|
||||
BG_IMAGE_FILL = 0
|
||||
WHITE_IMAGE_FILL = 1
|
||||
TRANS_IMAGE_FILL = 2
|
||||
|
||||
PARAM_INT32 = 0
|
||||
PARAM_INT16 = 1
|
||||
PARAM_INT8 = 2
|
||||
PARAM_FLOAT = 3
|
||||
PARAM_STRING = 4
|
||||
PARAM_INT32ARRAY = 5
|
||||
PARAM_INT16ARRAY = 6
|
||||
PARAM_INT8ARRAY = 7
|
||||
PARAM_FLOATARRAY = 8
|
||||
PARAM_STRINGARRAY = 9
|
||||
PARAM_COLOR = 10
|
||||
PARAM_REGION = 11
|
||||
PARAM_DISPLAY = 12
|
||||
PARAM_IMAGE = 13
|
||||
PARAM_LAYER = 14
|
||||
PARAM_CHANNEL = 15
|
||||
PARAM_DRAWABLE = 16
|
||||
PARAM_SELECTION = 17
|
||||
PARAM_BOUNDARY = 18
|
||||
PARAM_PATH = 19
|
||||
PARAM_STATUS = 20
|
||||
PARAM_END = 21
|
||||
|
||||
PROC_PLUG_IN = 1
|
||||
PROC_EXTENSION = 2
|
||||
PROC_TEMPORARY = 3
|
||||
|
||||
RUN_INTERACTIVE = 0
|
||||
RUN_NONINTERACTIVE = 1
|
||||
RUN_WITH_LAST_VALS = 2
|
||||
|
||||
STATUS_EXECUTION_ERROR = 0
|
||||
STATUS_CALLING_ERROR = 1
|
||||
STATUS_PASS_THROUGH = 2
|
||||
STATUS_SUCCESS = 3
|
||||
|
||||
# extra constants
|
||||
NORMAL = 0
|
||||
DISSOLVE = 1
|
||||
BEHIND = 2
|
||||
MULTIPLY = 3
|
||||
SCREEN = 4
|
||||
OVERLAY = 5
|
||||
DIFFERENCE = 6
|
||||
ADDITION = 7
|
||||
SUBTRACTION = 8
|
||||
DARKEN_ONLY = 9
|
||||
LIGHTEN_ONLY = 10
|
||||
HUE = 11
|
||||
SATURATION = 12
|
||||
COLOR = 13
|
||||
COLOUR = 13
|
||||
VALUE = 14
|
||||
|
||||
FG_BG_RGB = 0
|
||||
FG_BG_HSV = 1
|
||||
FG_TRANS = 2
|
||||
CUSTOM = 3
|
||||
|
||||
LINEAR = 0
|
||||
BILINEAR = 1
|
||||
RADIAL = 2
|
||||
SQUARE = 3
|
||||
CONICAL_SYMMETRIC = 4
|
||||
CONNUCAL_ASYMMETRIC = 5
|
||||
SHAPEBURST_ANGULAR = 6
|
||||
SHAPEBURST_SPHERICAL = 7
|
||||
SHAPEBURST_DIMPLED = 8
|
||||
|
||||
REPEAT_NONE = 0
|
||||
REPEAT_SAWTOOTH = 1
|
||||
REPEAT_TRIANGULAR = 2
|
||||
|
||||
FG_BUCKET_FILL = 0
|
||||
BG_BUCKET_FILL = 1
|
||||
PATTERN_BUCKET_FILL = 2
|
||||
|
||||
BG_IMAGE_FILL = 0
|
||||
WHITE_IMAGE_FILL = 1
|
||||
TRANS_IMAGE_FILL = 2
|
||||
NO_IMAGE_FILL = 3
|
||||
|
||||
RED_CHANNEL = 0
|
||||
GREEN_CHANNEL = 1
|
||||
BLUE_CHANNEL = 2
|
||||
GRAY_CHANNEL = 3
|
||||
GREY_CHANNEL = 3
|
||||
INDEXED_CHANNEL = 4
|
||||
|
||||
WHITE_MASK = 0
|
||||
BLACK_MASK = 1
|
||||
ALPHA_MASK = 2
|
||||
|
||||
APPLY = 0
|
||||
DISCARD = 1
|
||||
|
||||
EXPAND_AS_NECESSARY = 0
|
||||
CLIP_TO_IMAGE = 1
|
||||
CLIP_TO_BOTTOM_LAYER = 2
|
||||
|
||||
ADD = 0
|
||||
SUB = 1
|
||||
REPLACE = 2
|
||||
INTERSECT = 3
|
||||
|
||||
PIXELS = 0
|
||||
POINTS = 1
|
||||
|
||||
IMAGE_CLONE = 0
|
||||
PATTERN_CLONE = 1
|
||||
|
||||
BLUR = 0
|
||||
SHARPEN = 1
|
||||
|
||||
TRUE = 1
|
||||
FALSE = 0
|
||||
|
||||
import gimp
|
||||
if gimp.major_version > 1 or gimp.major_version==1 and gimp.minor_version>=1:
|
||||
PARASITE_PERSISTENT = 1
|
||||
PARASITE_UNDOABLE = 2
|
||||
PARASITE_ATTACH_PARENT = 0x80 << 8
|
||||
PARASITE_PARENT_PERSISTENT = PARASITE_PERSISTENT << 8
|
||||
PARASITE_PARENT_UNDOABLE = PARASITE_UNDOABLE << 8
|
||||
PARASITE_ATTACH_GRANDPARENT = 0x80 << 16
|
||||
PARASITE_GRANDPARENT_PERSISTENT = PARASITE_PERSISTENT << 16
|
||||
PARASITE_GRANDPARENT_UNDOABLE = PARASITE_UNDOABLE << 16
|
||||
|
||||
ORIENTATION_UNKNOWN = 0
|
||||
ORIENTATION_HORIZONTAL = 1
|
||||
ORIENTATION_VERTICAL = 2
|
||||
del gimp
|
495
plug-ins/pygimp/gimpfu.py
Normal file
495
plug-ins/pygimp/gimpfu.py
Normal file
@ -0,0 +1,495 @@
|
||||
'''Simple interface to writing GIMP plugins in python.
|
||||
|
||||
Instead of worrying about all the user interaction, saving last used values
|
||||
and everything, the gimpfu module can take care of it for you. It provides
|
||||
a simple register() function that will register your plugin if needed, and
|
||||
cause your plugin function to be called when needed.
|
||||
|
||||
Gimpfu will also handle showing a user interface for editing plugin parameters
|
||||
if the plugin is called interactively, and will also save the last used
|
||||
parameters, so the RUN_WITH_LAST_VALUES run_type will work correctly. It
|
||||
will also make sure that the displays are flushed on completion if the plugin
|
||||
was run interactively.
|
||||
|
||||
When registering the plugin, you do not need to worry about specifying
|
||||
the run_type parameter. And if the plugin is an image plugin (the menu
|
||||
path starts with <Image>/), the image and drawable parameters are also
|
||||
automatically added.
|
||||
|
||||
A typical gimpfu plugin would look like this:
|
||||
from gimpfu import *
|
||||
|
||||
def plugin_func(image, drawable, args):
|
||||
#do what plugins do best
|
||||
register(
|
||||
"plugin_func",
|
||||
"blurb",
|
||||
"help message",
|
||||
"author",
|
||||
"copyright",
|
||||
"year",
|
||||
"<Image>/Somewhere/My plugin",
|
||||
"*",
|
||||
[(PF_STRING, "arg", "The argument", "default-value")],
|
||||
[],
|
||||
plugin_func)
|
||||
main()
|
||||
|
||||
The call to "from gimpfu import *" will import all the gimp constants into
|
||||
the plugin namespace, and also import the symbols gimp, pdb, register and
|
||||
main. This should be just about all any plugin needs. You can use any
|
||||
of the PF_* constants below as parameter types, and an appropriate user
|
||||
interface element will be displayed when the plugin is run in interactive
|
||||
mode. Note that the the PF_SPINNER and PF_SLIDER types expect a fifth
|
||||
element in their description tuple -- a 3-tuple of the form (lower,upper,step),
|
||||
which defines the limits for the slider or spinner.'''
|
||||
|
||||
import string; _string = string; del string
|
||||
import gimp
|
||||
from gimpenums import *
|
||||
pdb = gimp.pdb
|
||||
|
||||
error = "gimpfu.error"
|
||||
|
||||
PF_INT8 = PARAM_INT8
|
||||
PF_INT16 = PARAM_INT16
|
||||
PF_INT32 = PARAM_INT32
|
||||
PF_INT = PF_INT32
|
||||
PF_FLOAT = PARAM_FLOAT
|
||||
PF_STRING = PARAM_STRING
|
||||
PF_VALUE = PF_STRING
|
||||
PF_INT8ARRAY = PARAM_INT8ARRAY
|
||||
PF_INT16ARRAY = PARAM_INT16ARRAY
|
||||
PF_INT32ARRAY = PARAM_INT32ARRAY
|
||||
PF_INTARRAY = PF_INT32ARRAY
|
||||
PF_FLOATARRAY = PARAM_FLOATARRAY
|
||||
PF_STRINGARRAY = PARAM_STRINGARRAY
|
||||
PF_COLOR = PARAM_COLOR
|
||||
PF_COLOUR = PF_COLOR
|
||||
PF_REGION = PARAM_REGION
|
||||
#PF_DISPLAY = PARAM_DISPLAY
|
||||
PF_IMAGE = PARAM_IMAGE
|
||||
PF_LAYER = PARAM_LAYER
|
||||
PF_CHANNEL = PARAM_CHANNEL
|
||||
PF_DRAWABLE = PARAM_DRAWABLE
|
||||
#PF_SELECTION = PARAM_SELECTION
|
||||
#PF_BOUNDARY = PARAM_BOUNDARY
|
||||
#PF_PATH = PARAM_PATH
|
||||
#PF_STATUS = PARAM_STATUS
|
||||
|
||||
PF_TOGGLE = 1000
|
||||
PF_BOOL = PF_TOGGLE
|
||||
PF_SLIDER = 1001
|
||||
PF_SPINNER = 1002
|
||||
PF_ADJUSTMENT = PF_SPINNER
|
||||
|
||||
PF_FONT = 1003
|
||||
PF_FILE = 1004
|
||||
PF_BRUSH = 1005
|
||||
PF_PATTERN = 1006
|
||||
PF_GRADIENT = 1007
|
||||
|
||||
_type_mapping = {
|
||||
PF_INT8 : PARAM_INT8,
|
||||
PF_INT16 : PARAM_INT16,
|
||||
PF_INT32 : PARAM_INT32,
|
||||
PF_FLOAT : PARAM_FLOAT,
|
||||
PF_STRING : PARAM_STRING,
|
||||
PF_INT8ARRAY : PARAM_INT8ARRAY,
|
||||
PF_INT16ARRAY : PARAM_INT16ARRAY,
|
||||
PF_INT32ARRAY : PARAM_INT32ARRAY,
|
||||
PF_FLOATARRAY : PARAM_FLOATARRAY,
|
||||
PF_STRINGARRAY : PARAM_STRINGARRAY,
|
||||
PF_COLOUR : PARAM_COLOR,
|
||||
PF_REGION : PARAM_REGION,
|
||||
PF_IMAGE : PARAM_IMAGE,
|
||||
PF_LAYER : PARAM_LAYER,
|
||||
PF_CHANNEL : PARAM_CHANNEL,
|
||||
PF_DRAWABLE : PARAM_DRAWABLE,
|
||||
|
||||
PF_TOGGLE : PARAM_INT32,
|
||||
PF_SLIDER : PARAM_FLOAT,
|
||||
PF_SPINNER : PARAM_INT32,
|
||||
|
||||
PF_FONT : PARAM_STRING,
|
||||
PF_FILE : PARAM_STRING,
|
||||
PF_BRUSH : PARAM_STRING,
|
||||
PF_PATTERN : PARAM_STRING,
|
||||
PF_GRADIENT : PARAM_STRING
|
||||
}
|
||||
|
||||
_registered_plugins_ = {}
|
||||
|
||||
def register(func_name, blurb, help, author, copyright, date, menupath,
|
||||
imagetypes, params, results, function):
|
||||
'''This is called to register a new plugin.'''
|
||||
# First perform some sanity checks on the data
|
||||
def letterCheck(str):
|
||||
allowed = _string.letters + _string.digits + '_'
|
||||
for ch in str:
|
||||
if not ch in allowed:
|
||||
return 0
|
||||
else:
|
||||
return 1
|
||||
if not letterCheck(func_name):
|
||||
raise error, "function name contains ileagal characters"
|
||||
for ent in params:
|
||||
if len(ent) < 4:
|
||||
raise error, "sequence not long enough for "+ent[0]
|
||||
if type(ent[0]) != type(42):
|
||||
raise error, "parameter types must be integers"
|
||||
if not letterCheck(ent[1]):
|
||||
raise error,"parameter name contains ilegal characters"
|
||||
for ent in results:
|
||||
if len(ent) < 3:
|
||||
raise error, "sequence not long enough for "+ent[0]
|
||||
if type(ent[0]) != type(42):
|
||||
raise error, "result types must be integers"
|
||||
if not letterCheck(ent[1]):
|
||||
raise error,"result name contains ilegal characters"
|
||||
if menupath[:8] == '<Image>/':
|
||||
plugin_type = PROC_PLUG_IN
|
||||
elif menupath[:10] == '<Toolbox>/':
|
||||
plugin_type = PROC_EXTENSION
|
||||
else:
|
||||
raise error, "menu path must start with <Image> or <Toolbox>"
|
||||
|
||||
if not func_name[:7] == 'python_' and \
|
||||
not func_name[:10] == 'extension_' and \
|
||||
not func_name[:8] == 'plug_in_':
|
||||
func_name = 'python_fu_' + func_name
|
||||
|
||||
_registered_plugins_[func_name] = (blurb, help, author, copyright,
|
||||
date, menupath, imagetypes,
|
||||
plugin_type, params, results,
|
||||
function)
|
||||
|
||||
def _query():
|
||||
for plugin in _registered_plugins_.keys():
|
||||
(blurb, help, author, copyright, date,
|
||||
menupath, imagetypes, plugin_type,
|
||||
params, results, function) = _registered_plugins_[plugin]
|
||||
|
||||
fn = lambda x: (_type_mapping[x[0]], x[1], x[2])
|
||||
params = map(fn, params)
|
||||
# add the run mode argument ...
|
||||
params.insert(0, (PARAM_INT32, "run_mode",
|
||||
"Interactive, Non-Interactive"))
|
||||
if plugin_type == PROC_PLUG_IN:
|
||||
params.insert(1, (PARAM_IMAGE, "image",
|
||||
"The image to work on"))
|
||||
params.insert(2, (PARAM_DRAWABLE, "drawable",
|
||||
"The drawable to work on"))
|
||||
results = map(fn, results)
|
||||
gimp.install_procedure(plugin, blurb, help, author, copyright,
|
||||
date, menupath, imagetypes, plugin_type,
|
||||
params, results)
|
||||
|
||||
def _get_defaults(func_name):
|
||||
import gimpshelf
|
||||
(blurb, help, author, copyright, date,
|
||||
menupath, imagetypes, plugin_type,
|
||||
params, results, function) = _registered_plugins_[func_name]
|
||||
|
||||
key = "python-fu-save--" + func_name
|
||||
if gimpshelf.shelf.has_key(key):
|
||||
return gimpshelf.shelf[key]
|
||||
else:
|
||||
# return the default values
|
||||
return map(lambda x: x[3], params)
|
||||
|
||||
def _set_defaults(func_name, defaults):
|
||||
import gimpshelf
|
||||
|
||||
key = "python-fu-save--" + func_name
|
||||
gimpshelf.shelf[key] = defaults
|
||||
|
||||
def _interact(func_name):
|
||||
(blurb, help, author, copyright, date,
|
||||
menupath, imagetypes, plugin_type,
|
||||
params, results, function) = _registered_plugins_[func_name]
|
||||
|
||||
# short circuit for no parameters ...
|
||||
if len(params) == 0: return []
|
||||
|
||||
import gtk
|
||||
import gimpui
|
||||
|
||||
gtk.rc_parse(gimp.gtkrc())
|
||||
|
||||
defaults = _get_defaults(func_name)
|
||||
# define a mapping of param types to edit objects ...
|
||||
class StringEntry(gtk.GtkEntry):
|
||||
def __init__(self, default=''):
|
||||
import gtk
|
||||
gtk.GtkEntry.__init__(self)
|
||||
self.set_text(str(default))
|
||||
def get_value(self):
|
||||
return self.get_text()
|
||||
class IntEntry(StringEntry):
|
||||
def get_value(self):
|
||||
import string
|
||||
return string.atoi(self.get_text())
|
||||
class FloatEntry(StringEntry):
|
||||
def get_value(self):
|
||||
import string
|
||||
return string.atof(self.get_text())
|
||||
class ArrayEntry(StringEntry):
|
||||
def get_value(self):
|
||||
return eval(self.get_text())
|
||||
class SliderEntry(gtk.GtkHScale):
|
||||
# bounds is (upper, lower, step)
|
||||
def __init__(self, default=0, bounds=(0, 100, 5)):
|
||||
import gtk
|
||||
self.adj = gtk.GtkAdjustment(default, bounds[0],
|
||||
bounds[1], bounds[2],
|
||||
bounds[2], bounds[2])
|
||||
gtk.GtkHScale.__init__(self, self.adj)
|
||||
def get_value(self):
|
||||
return self.adj.value
|
||||
class SpinnerEntry(gtk.GtkSpinButton):
|
||||
# bounds is (upper, lower, step)
|
||||
def __init__(self, default=0, bounds=(0, 100, 5)):
|
||||
import gtk
|
||||
self.adj = gtk.GtkAdjustment(default, bounds[0],
|
||||
bounds[1], bounds[2],
|
||||
bounds[2], bounds[2])
|
||||
gtk.GtkSpinButton.__init__(self, self.adj, 1, 0)
|
||||
def get_value(self):
|
||||
return int(self.adj.value)
|
||||
class ToggleEntry(gtk.GtkToggleButton):
|
||||
def __init__(self, default=0):
|
||||
import gtk
|
||||
gtk.GtkToggleButton.__init__(self)
|
||||
self.label = gtk.GtkLabel("No")
|
||||
self.add(self.label)
|
||||
self.label.show()
|
||||
self.connect("toggled", self.changed)
|
||||
self.set_active(default)
|
||||
def changed(self, tog):
|
||||
if tog.active:
|
||||
self.label.set_text("Yes")
|
||||
else:
|
||||
self.label.set_text("No")
|
||||
def get_value(self):
|
||||
return self.get_active()
|
||||
|
||||
_edit_mapping = {
|
||||
PF_INT8 : IntEntry,
|
||||
PF_INT16 : IntEntry,
|
||||
PF_INT32 : IntEntry,
|
||||
PF_FLOAT : FloatEntry,
|
||||
PF_STRING : StringEntry,
|
||||
PF_INT8ARRAY : ArrayEntry,
|
||||
PF_INT16ARRAY : ArrayEntry,
|
||||
PF_INT32ARRAY : ArrayEntry,
|
||||
PF_FLOATARRAY : ArrayEntry,
|
||||
PF_STRINGARRAY : ArrayEntry,
|
||||
PF_COLOUR : gimpui.ColourSelector,
|
||||
PF_REGION : IntEntry, # should handle differently ...
|
||||
PF_IMAGE : gimpui.ImageSelector,
|
||||
PF_LAYER : gimpui.LayerSelector,
|
||||
PF_CHANNEL : gimpui.ChannelSelector,
|
||||
PF_DRAWABLE : gimpui.DrawableSelector,
|
||||
|
||||
PF_TOGGLE : ToggleEntry,
|
||||
PF_SLIDER : SliderEntry,
|
||||
PF_SPINNER : SpinnerEntry,
|
||||
|
||||
PF_FONT : gimpui.FontSelector,
|
||||
PF_FILE : gimpui.FileSelector,
|
||||
PF_BRUSH : gimpui.BrushSelector,
|
||||
PF_PATTERN : gimpui.PatternSelector,
|
||||
PF_GRADIENT : gimpui.GradientSelector,
|
||||
}
|
||||
|
||||
tooltips = gtk.GtkTooltips()
|
||||
|
||||
dialog = gtk.GtkDialog()
|
||||
dialog.set_title(func_name)
|
||||
table = gtk.GtkTable(len(params), 3, gtk.FALSE)
|
||||
table.set_border_width(5)
|
||||
table.set_row_spacings(2)
|
||||
table.set_col_spacings(10)
|
||||
dialog.vbox.pack_start(table)
|
||||
table.show()
|
||||
|
||||
vbox = gtk.GtkVBox(gtk.FALSE, 15)
|
||||
table.attach(vbox, 0,1, 0,len(params), xoptions=gtk.FILL)
|
||||
vbox.show()
|
||||
pix = _get_logo(vbox.get_colormap())
|
||||
vbox.pack_start(pix, expand=gtk.FALSE)
|
||||
pix.show()
|
||||
|
||||
label = gtk.GtkLabel(blurb)
|
||||
label.set_line_wrap(TRUE)
|
||||
label.set_justify(gtk.JUSTIFY_LEFT)
|
||||
label.set_usize(100, -1)
|
||||
vbox.pack_start(label, expand=gtk.FALSE)
|
||||
label.show()
|
||||
|
||||
edit_wids = []
|
||||
for i in range(len(params)):
|
||||
type = params[i][0]
|
||||
name = params[i][1]
|
||||
desc = params[i][2]
|
||||
def_val = defaults[i]
|
||||
|
||||
label = gtk.GtkLabel(name)
|
||||
label.set_alignment(1.0, 0.5)
|
||||
table.attach(label, 1,2, i,i+1, xoptions=gtk.FILL)
|
||||
label.show()
|
||||
|
||||
if type in (PF_SPINNER, PF_SLIDER):
|
||||
wid = _edit_mapping[type](def_val, params[i][4])
|
||||
else:
|
||||
wid = _edit_mapping[type](def_val)
|
||||
table.attach(wid, 2,3, i,i+1)
|
||||
tooltips.set_tip(wid, desc, None)
|
||||
wid.show()
|
||||
edit_wids.append(wid)
|
||||
|
||||
def delete_event(win, event=None):
|
||||
import gtk
|
||||
win.hide()
|
||||
gtk.mainquit()
|
||||
return TRUE
|
||||
|
||||
# this is a hack ...
|
||||
finished = [ 0 ]
|
||||
def ok_clicked(button, win=dialog, finished=finished):
|
||||
import gtk
|
||||
win.hide()
|
||||
finished[0] = 1
|
||||
gtk.mainquit()
|
||||
b = gtk.GtkButton("OK")
|
||||
b.set_flags(gtk.CAN_DEFAULT)
|
||||
dialog.action_area.pack_start(b)
|
||||
b.grab_default()
|
||||
b.connect("clicked", ok_clicked)
|
||||
b.show()
|
||||
|
||||
b = gtk.GtkButton("Cancel")
|
||||
b.set_flags(gtk.CAN_DEFAULT)
|
||||
dialog.action_area.pack_start(b)
|
||||
b.connect("clicked", delete_event)
|
||||
b.show()
|
||||
|
||||
dialog.show()
|
||||
tooltips.enable()
|
||||
# run the main loop
|
||||
gtk.mainloop()
|
||||
ret = None
|
||||
if finished[0]:
|
||||
# OK was clicked
|
||||
ret = map(lambda wid: wid.get_value(), edit_wids)
|
||||
_set_defaults(func_name, ret)
|
||||
dialog.destroy()
|
||||
return ret
|
||||
|
||||
def _run(func_name, params):
|
||||
run_mode = params[0]
|
||||
plugin_type = _registered_plugins_[func_name][7]
|
||||
func = _registered_plugins_[func_name][10]
|
||||
|
||||
if plugin_type == PROC_PLUG_IN:
|
||||
start_params = params[1:3]
|
||||
extra_params = params[3:]
|
||||
else:
|
||||
start_params = ()
|
||||
extra_params = params[1:]
|
||||
|
||||
if run_mode == RUN_INTERACTIVE:
|
||||
extra_params = _interact(func_name)
|
||||
if extra_params == None:
|
||||
return
|
||||
elif run_mode == RUN_WITH_LAST_VALS:
|
||||
extra_params = _get_defaults(func_name)
|
||||
|
||||
params = start_params + tuple(extra_params)
|
||||
res = apply(func, params)
|
||||
if run_mode != RUN_NONINTERACTIVE: gimp.displays_flush()
|
||||
|
||||
def main():
|
||||
'''This should be called after registering the plugin.'''
|
||||
gimp.main(None, None, _query, _run)
|
||||
|
||||
_python_image = [
|
||||
"64 64 7 1",
|
||||
" c #000000",
|
||||
". c #00FF00",
|
||||
"X c None",
|
||||
"o c #FF0000",
|
||||
"O c #FFFF00",
|
||||
"+ c #808000",
|
||||
"@ c #0000FF",
|
||||
"XXXXXXXXXXXXXX XX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXXXXXX XX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXXXX ++++ ++++++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXXXX ++++ ++++++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXX ++++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXX ++++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXX OOOO OOOOOO ++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXX OOOO OOOOOO ++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXX OO@@ OO@@@@ ++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXX OO@@ OO@@@@ ++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXX OO@@ OO@@@@ ++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXX OO@@ OO@@@@ ++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXX OOOO OOOOOO ++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXX OOOO OOOOOO ++ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXX ++ ++++++ XXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXX ++ ++++++ XXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXX ++++++++++++++++++++++ ++++++ XXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXX ++++++++++++++++++++++ ++++++ XXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XX ++++++++++++++++++++++++++++ ++++++++ XXXXXXXXXXXXXXXXXXXX",
|
||||
"XX ++++++++++++++++++++++++++++ ++++++++ XXXXXXXXXXXXXXXXXXXX",
|
||||
" ++++++++++++++++++++++++++++++++ ++++++++ XXXXXXXXXXXXXXXXXX",
|
||||
" ++++++++++++++++++++++.+.+..++++ ++++++++ XXXXXXXXXXXXXXXXXX",
|
||||
" ++ ++++ ++++++++++.+........++ ++++++++ XXXXXXXXXXXXXXXXXX",
|
||||
" ++ ++++ ++++++++.+...........+ ++++++++ XXXXXXXXXXXXXXXXXX",
|
||||
" ++++++++++++++++++.+.. ...... ++++++++++ XXXXXXXXXXXXXXXX",
|
||||
" ++++++++++++++++.+... ...... ++++++++++ XXXXXXXXXXXXXXXX",
|
||||
" .+.+.+.+.+.+.+.+.... ..++.. ..++++++++++ XXXXXXXXXXXXXXXX",
|
||||
" .+.+.+.+.+.+.+..... ..++.. ...+++++++++ XXXXXXXXXXXXXXXX",
|
||||
" ................ ++.... ......++++++++ XXXXXXXXXXXXXXXX",
|
||||
" ............... +..... +......+++++++ XXXXXXXXXXXXXXXX",
|
||||
"XX +.+.+.+.+..+ ++++.. ++++...+++++++ XXXXXXXXXXXXXXXX",
|
||||
"XX ++++++++++++ +...... ++++...+++++++ XXXXXXXXXXXXXXXX",
|
||||
"XXXX ooooo ++.... XX +......+++++++ XXXXXXXXXXXXXXXX",
|
||||
"XXXX ooooo ++..... XX .......+++++++ XXXXXXXXXXXXXXXX",
|
||||
"XXXX ooooo ++...... XXXX ++....++++++ XXXXXXXXXXXXXXXXXX",
|
||||
"XXXX ooooo ++....... XXXX ++...+++++++ XXXXXXXXXXXXXXXXXX",
|
||||
"XXXX ooooo.++...... XXXX +......+++++++ XXXXXXXXXXXXXXXXXX",
|
||||
"XXXX ooooo..+....... XXXX ......++++++++ XXXXXXXXXXXXXXXXXX",
|
||||
"XXXXooooo....... XXXX +++++....+++++++ XXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXooooo........ XXXX +++++..+++++++++ XXXXXXXXXXXXXXXXXXXX",
|
||||
"XXoooo XXXXXX +.......++++++++ XXXXXXXXXXXXXXXXXXXXXX",
|
||||
"Xooooo XXXXXX .......+++++++++ XXXXXXXXXXXXXXXXXXXXXX",
|
||||
"oooXooXXXXXXXXXXXX +++++....+++++++++ XXXXXXXXXXXXXXXXXXXXXX ",
|
||||
"ooXXooXXXXXXXXXXXX +++++...++++++++++ XXXXXXXXXXXXXXXXXXXXXX ",
|
||||
"XXXXooXXXXXXXX ++.......+++++++++ XXXXXXXXXXXXXXXXXXXXXX ",
|
||||
"XXXXooXXXXXXXX +.......++++++++++ XXXXXXXXXXXXXXXXXXXXXX ",
|
||||
"XXXXXXXXXXXX ++++++.....+++++++++ XXXXXX XXXX ++ ",
|
||||
"XXXXXXXXXXXX ++++++....++++++++++ XXXXXX XXXX ++ ",
|
||||
"XXXXXXXXXXXX +........+++++++++ ++++++++ XX ++++++ ++++ ",
|
||||
"XXXXXXXXXXXX ........++++++++++ ++++++++ XX ++++++ ++++ ",
|
||||
"XXXXXXXXXX ..........++++++++ ++++++++++++ ++++++++++++++++ ",
|
||||
"XXXXXXXXXX .........+++++++++ ++++++++++++ ++++++++++++++++ ",
|
||||
"XXXXXXXXXX ++++....++++++++++++++++++++++++++++++++++++++++ XX",
|
||||
"XXXXXXXXXX +++++...++++++++++++++++++++++++++++++++++++++++ XX",
|
||||
"XXXXXXXXXX ++++....++++++++++++++++++++++++++++++ ..... XXXX",
|
||||
"XXXXXXXXXX ........++++++++++++++++++++++++++++++ .... XXXX",
|
||||
"XXXXXXXXXX .........+++++++++++..++++++++++++++ XXXX XXXXXX",
|
||||
"XXXXXXXXXX .............+++++++..++++++++++++++ XXXX XXXXXX",
|
||||
"XXXXXXXXXXXX +++++............ ............ XXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXXXX ++++++.......... .......... XXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXXXXXX +.....++.. XXXX XXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXXXXXX .....++++. XXXX XXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
]
|
||||
|
||||
def _get_logo(colormap):
|
||||
import gtk
|
||||
pix, mask = gtk.create_pixmap_from_xpm_d(colormap, None, _python_image)
|
||||
return gtk.GtkPixmap(pix, mask)
|
4607
plug-ins/pygimp/gimpmodule.c
Normal file
4607
plug-ins/pygimp/gimpmodule.c
Normal file
File diff suppressed because it is too large
Load Diff
56
plug-ins/pygimp/gimpplugin.py
Normal file
56
plug-ins/pygimp/gimpplugin.py
Normal file
@ -0,0 +1,56 @@
|
||||
# Gimp-Python - allows the writing of Gimp plugins in Python.
|
||||
# Copyright (C) 1997 James Henstridge <james@daa.com.au>
|
||||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
# plugin.py -- helper for writing gimp plugins
|
||||
# Copyright (C) 1997, James Henstridge.
|
||||
#
|
||||
# This is a small wrapper that makes plugins look like an object class that
|
||||
# you can derive to create your plugin. With this wrapper, you are pretty
|
||||
# much responsible for doing everything (checking run_mode, gui, etc). If
|
||||
# you want to write a quick plugin, you probably want the gimpfu module.
|
||||
#
|
||||
# A plugin using this module would look something like this:
|
||||
#
|
||||
# import gimp, gimpplugin
|
||||
# pdb = gimp.pdb
|
||||
# class myplugin(gimpplugin.plugin):
|
||||
# def query(self):
|
||||
# gimp.install_procedure("plug_in_mine", ...)
|
||||
# def plug_in_mine(self, par1, par2, par3,...):
|
||||
# do_something()
|
||||
#
|
||||
# if __name__ == '__main__': myplugin().start()
|
||||
|
||||
import gimp
|
||||
|
||||
class plugin:
|
||||
def start(self):
|
||||
gimp.main(self.init, self.quit, self.query, self._run)
|
||||
def init(self):
|
||||
pass
|
||||
def quit(self):
|
||||
pass
|
||||
def query(self):
|
||||
pass
|
||||
def _run(self, name, params):
|
||||
if hasattr(self, name):
|
||||
apply(getattr(self, name), params)
|
||||
else:
|
||||
raise AttributeError, name
|
||||
|
||||
if __name__ == '__main__': plugin().start()
|
||||
|
83
plug-ins/pygimp/gimpshelf.py
Normal file
83
plug-ins/pygimp/gimpshelf.py
Normal file
@ -0,0 +1,83 @@
|
||||
# Gimp-Python - allows the writing of Gimp plugins in Python.
|
||||
# Copyright (C) 1997 James Henstridge <james@daa.com.au>
|
||||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
# gimshelf.py -- a simple module to help gimp modules written in Python
|
||||
# store persistent data.
|
||||
#
|
||||
# Copyright (C) 1997, James Henstridge
|
||||
#
|
||||
# The gimp module provides a basic method for storing information that persists
|
||||
# for a whole gimp session, but only allows for the storage of strings. This
|
||||
# is because other Python types usually have pointers to other Python objects,
|
||||
# making it dificult to work out what to save. This module gives an interface
|
||||
# to the gimp module's primitive interface, which resembles the shelve module.
|
||||
|
||||
try:
|
||||
# use cPickle instead of pickle if it is available.
|
||||
import cPickle
|
||||
pickle = cPickle
|
||||
del cPickle
|
||||
except ImportError:
|
||||
import pickle
|
||||
import StringIO
|
||||
import gimp
|
||||
|
||||
try:
|
||||
# this will fail with python 1.4. All we lose is that the values
|
||||
# for a plugin which takes extra image/drawables/etc will not be
|
||||
# saved between invocations.
|
||||
import copy_reg
|
||||
def _image_id(obj):
|
||||
return gimp._id2image, (obj.ID,)
|
||||
def _drawable_id(obj):
|
||||
return gimp._id2drawable, (obj.ID,)
|
||||
def _display_id(obj):
|
||||
return gimp._id2display, int(obj)
|
||||
copy_reg.pickle(gimp.ImageType, _image_id, gimp._id2image)
|
||||
copy_reg.pickle(gimp.LayerType, _drawable_id, gimp._id2drawable)
|
||||
copy_reg.pickle(gimp.ChannelType, _drawable_id, gimp._id2drawable)
|
||||
copy_reg.pickle(gimp.DisplayType, _display_id, gimp._id2display)
|
||||
del copy_reg, _image_id, _drawable_id, _display_id
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
class Gimpshelf:
|
||||
def has_key(self, key):
|
||||
try:
|
||||
s = gimp.get_data(key)
|
||||
return 1
|
||||
except gimp.error:
|
||||
return 0
|
||||
|
||||
def __getitem__(self, key):
|
||||
try:
|
||||
s = gimp.get_data(key)
|
||||
except gimp.error:
|
||||
raise KeyError, key
|
||||
f = StringIO.StringIO(s)
|
||||
return pickle.Unpickler(f).load()
|
||||
def __setitem__(self, key, value):
|
||||
f = StringIO.StringIO()
|
||||
p = pickle.Pickler(f)
|
||||
p.dump(value)
|
||||
gimp.set_data(key, f.getvalue())
|
||||
def __delitem__(self, key):
|
||||
gimp.set_data(key, '')
|
||||
|
||||
shelf = Gimpshelf()
|
||||
del Gimpshelf
|
||||
|
364
plug-ins/pygimp/gimpui.py
Normal file
364
plug-ins/pygimp/gimpui.py
Normal file
@ -0,0 +1,364 @@
|
||||
'''This module implements the UI items found in the libgimpui library.
|
||||
It requires pygtk to work. These functions take use to callbacks -- one
|
||||
is a constraint function, and the other is the callback object. The
|
||||
constraint function takes an image object as its first argument, and
|
||||
a drawable object as its second if appropriate. The callback functions
|
||||
get the selected object as their first argument, and the user data as
|
||||
the second.
|
||||
|
||||
It also implements a number of selector widgets, which can be used to select
|
||||
various gimp data types. Each of these selectors takes default as an argument
|
||||
to the constructor, and has a get_value() method for retrieving the result.
|
||||
'''
|
||||
|
||||
import gtk, gimp
|
||||
|
||||
def _callbackWrapper(menu_item, callback, data):
|
||||
callback(menu_item.get_data("Gimp-ID"), data)
|
||||
|
||||
def _createMenu(items, callback, data):
|
||||
menu = gtk.GtkMenu()
|
||||
if not items:
|
||||
items = [("(none)", None)]
|
||||
for label, id in items:
|
||||
menu_item = gtk.GtkMenuItem(label)
|
||||
menu_item.set_data("Gimp-ID", id)
|
||||
menu.add(menu_item)
|
||||
if callback:
|
||||
menu_item.connect("activate", _callbackWrapper,
|
||||
callback, data)
|
||||
menu_item.show()
|
||||
return menu
|
||||
|
||||
|
||||
def ImageMenu(constraint=None, callback=None, data=None):
|
||||
items = []
|
||||
for img in gimp.query_images():
|
||||
if constraint and not constraint(img):
|
||||
continue
|
||||
items.append((img.filename, img))
|
||||
items.sort()
|
||||
return _createMenu(items, callback, data)
|
||||
|
||||
def LayerMenu(constraint=None, callback=None, data=None):
|
||||
items = []
|
||||
for img in gimp.query_images():
|
||||
filename = img.filename
|
||||
for layer in img.layers:
|
||||
if constraint and not constraint(img, layer):
|
||||
continue
|
||||
name = filename + "/" + layer.name
|
||||
items.append((name, layer))
|
||||
items.sort()
|
||||
return _createMenu(items, callback, data)
|
||||
|
||||
def ChannelMenu(constraint=None, callback=None, data=None):
|
||||
items = []
|
||||
for img in gimp.query_images():
|
||||
filename = img.filename
|
||||
for channel in img.channels:
|
||||
if constraint and not constraint(img, channel):
|
||||
continue
|
||||
name = filename + "/" + channel.name
|
||||
items.append((name, channel))
|
||||
items.sort()
|
||||
return _createMenu(items, callback, data)
|
||||
|
||||
def DrawableMenu(constraint=None, callback=None, data=None):
|
||||
items = []
|
||||
for img in gimp.query_images():
|
||||
filename = img.filename
|
||||
for drawable in img.layers + img.channels:
|
||||
if constraint and not constraint(img, drawable):
|
||||
continue
|
||||
name = filename + "/" + drawable.name
|
||||
items.append((name, drawable))
|
||||
items.sort()
|
||||
return _createMenu(items, callback, data)
|
||||
|
||||
class ImageSelector(gtk.GtkOptionMenu):
|
||||
def __init__(self, default=None):
|
||||
gtk.GtkOptionMenu.__init__(self)
|
||||
self.menu = ImageMenu(None, self.clicked)
|
||||
self.set_menu(self.menu)
|
||||
self.selected = default
|
||||
children = self.menu.children()
|
||||
for child in range(len(children)):
|
||||
if children[child].get_data("Gimp-ID") == default:
|
||||
self.set_history(child)
|
||||
break
|
||||
def clicked(self, img, data=None):
|
||||
self.selected = img
|
||||
def get_value(self):
|
||||
return self.selected
|
||||
|
||||
class LayerSelector(gtk.GtkOptionMenu):
|
||||
def __init__(self, default=None):
|
||||
gtk.GtkOptionMenu.__init__(self)
|
||||
self.menu = LayerMenu(None, self.clicked)
|
||||
self.set_menu(self.menu)
|
||||
self.selected = default
|
||||
children = self.menu.children()
|
||||
for child in range(len(children)):
|
||||
if children[child].get_data("Gimp-ID") == default:
|
||||
self.set_history(child)
|
||||
break
|
||||
def clicked(self, layer, data=None):
|
||||
self.selected = layer
|
||||
def get_value(self):
|
||||
return self.selected
|
||||
|
||||
class ChannelSelector(gtk.GtkOptionMenu):
|
||||
def __init__(self, default=None):
|
||||
gtk.GtkOptionMenu.__init__(self)
|
||||
self.menu = ChannelMenu(None, self.clicked)
|
||||
self.set_menu(self.menu)
|
||||
self.selected = default
|
||||
children = self.menu.children()
|
||||
for child in range(len(children)):
|
||||
if children[child].get_data("Gimp-ID") == default:
|
||||
self.set_history(child)
|
||||
break
|
||||
def clicked(self, channel, data=None):
|
||||
self.selected = channel
|
||||
def get_value(self):
|
||||
return self.selected
|
||||
|
||||
class DrawableSelector(gtk.GtkOptionMenu):
|
||||
def __init__(self, default=None):
|
||||
gtk.GtkOptionMenu.__init__(self)
|
||||
self.menu = DrawableMenu(None, self.clicked)
|
||||
self.set_menu(self.menu)
|
||||
self.selected = default
|
||||
children = self.menu.children()
|
||||
for child in range(len(children)):
|
||||
if children[child].get_data("Gimp-ID") == default:
|
||||
self.set_history(child)
|
||||
break
|
||||
def clicked(self, drawable, data=None):
|
||||
self.selected = drawable
|
||||
def get_value(self):
|
||||
return self.selected
|
||||
|
||||
class ColourSelector(gtk.GtkButton):
|
||||
def __init__(self, default=(255, 0, 0)):
|
||||
gtk.GtkButton.__init__(self)
|
||||
self.set_usize(100, 20)
|
||||
|
||||
self.colour = default
|
||||
self.update_colour()
|
||||
|
||||
self.dialog = None
|
||||
self.connect("clicked", self.show_dialog)
|
||||
def update_colour(self):
|
||||
r, g, b = self.colour
|
||||
colour = self.get_colormap().alloc(r*256, g*256, b*256)
|
||||
style = self.get_style().copy()
|
||||
style.bg[gtk.STATE_NORMAL] = colour
|
||||
style.bg[gtk.STATE_PRELIGHT] = colour
|
||||
self.set_style(style)
|
||||
self.queue_draw()
|
||||
|
||||
def show_dialog(self, button):
|
||||
if self.dialog:
|
||||
self.dialog.show()
|
||||
return
|
||||
self.dialog = gtk.GtkColorSelectionDialog("Colour")
|
||||
self.dialog.colorsel.set_color(tuple(map(lambda x: x/255.0,
|
||||
self.colour)))
|
||||
def delete_event(win, event):
|
||||
win.hide()
|
||||
return gtk.TRUE
|
||||
self.dialog.connect("delete_event", delete_event)
|
||||
self.dialog.ok_button.connect("clicked", self.selection_ok)
|
||||
self.dialog.cancel_button.connect("clicked", self.dialog.hide)
|
||||
self.dialog.show()
|
||||
|
||||
def selection_ok(self, button):
|
||||
colour = self.dialog.colorsel.get_color()
|
||||
self.colour = tuple(map(lambda x: int(x*255.99), colour))
|
||||
self.update_colour()
|
||||
self.dialog.hide()
|
||||
|
||||
def get_value(self):
|
||||
return self.colour
|
||||
|
||||
class _Selector(gtk.GtkHBox):
|
||||
def __init__(self):
|
||||
gtk.GtkHBox.__init__(self, gtk.FALSE, 5)
|
||||
self.entry = gtk.GtkEntry()
|
||||
self.pack_start(self.entry)
|
||||
self.entry.show()
|
||||
self.button = gtk.GtkButton("...")
|
||||
self.button.connect("clicked", self.show_dialog)
|
||||
self.pack_start(self.button, expand=gtk.FALSE)
|
||||
self.button.show()
|
||||
|
||||
self.dialog = gtk.GtkDialog()
|
||||
self.dialog.set_title(self.get_title())
|
||||
def delete_event(win, event):
|
||||
win.hide()
|
||||
return gtk.TRUE
|
||||
self.dialog.connect("delete_event", delete_event)
|
||||
|
||||
box = gtk.GtkVBox()
|
||||
box.set_border_width(5)
|
||||
self.dialog.vbox.pack_start(box)
|
||||
box.show()
|
||||
|
||||
swin = gtk.GtkScrolledWindow()
|
||||
swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||
box.pack_start(swin)
|
||||
swin.show()
|
||||
|
||||
items = map(None, self.get_list())
|
||||
list = gtk.GtkList()
|
||||
list.set_selection_mode(gtk.SELECTION_BROWSE)
|
||||
self.selected = self.get_default()
|
||||
self.entry.set_text(self.selected)
|
||||
items.sort()
|
||||
for s in items:
|
||||
item = gtk.GtkListItem(s)
|
||||
list.add(item)
|
||||
if s == self.selected:
|
||||
list.select_child(item)
|
||||
item.show()
|
||||
swin.add_with_viewport(list)
|
||||
list.show()
|
||||
|
||||
b = gtk.GtkButton("OK")
|
||||
self.dialog.action_area.pack_start(b)
|
||||
b.set_flags(gtk.CAN_DEFAULT)
|
||||
b.grab_default()
|
||||
b.show()
|
||||
b.connect("clicked", self.selection_ok, list)
|
||||
|
||||
b = gtk.GtkButton("Cancel")
|
||||
self.dialog.action_area.pack_start(b)
|
||||
b.set_flags(gtk.CAN_DEFAULT)
|
||||
b.show()
|
||||
b.connect("clicked", self.dialog.hide)
|
||||
|
||||
self.dialog.set_usize(300, 225)
|
||||
|
||||
def show_dialog(self, button):
|
||||
self.dialog.show()
|
||||
|
||||
def selection_ok(self, button, list):
|
||||
self.dialog.hide()
|
||||
|
||||
sel = list.get_selection()
|
||||
if not sel: return
|
||||
self.selected = sel[0].children()[0].get()
|
||||
self.entry.set_text(self.selected)
|
||||
|
||||
def get_value(self):
|
||||
return self.selected
|
||||
|
||||
class PatternSelector(_Selector):
|
||||
def __init__(self, default=""):
|
||||
self.default = default
|
||||
_Selector.__init__(self)
|
||||
def get_default(self):
|
||||
return self.default
|
||||
def get_title(self):
|
||||
return "Patterns"
|
||||
def get_list(self):
|
||||
num, patterns = gimp.pdb.gimp_patterns_list()
|
||||
return patterns
|
||||
|
||||
class BrushSelector(_Selector):
|
||||
def __init__(self, default=""):
|
||||
self.default = default
|
||||
_Selector.__init__(self)
|
||||
def get_default(self):
|
||||
return self.default
|
||||
def get_title(self):
|
||||
return "Brushes"
|
||||
def get_list(self):
|
||||
num, brushes = gimp.pdb.gimp_brushes_list()
|
||||
return brushes
|
||||
|
||||
class GradientSelector(_Selector):
|
||||
def __init__(self, default=""):
|
||||
self.default = default
|
||||
_Selector.__init__(self)
|
||||
def get_default(self):
|
||||
return self.default
|
||||
def get_title(self):
|
||||
return "Gradients"
|
||||
def get_list(self):
|
||||
num, gradients = gimp.pdb.gimp_gradients_get_list()
|
||||
return gradients
|
||||
|
||||
class FontSelector(gtk.GtkHBox):
|
||||
def __init__(self, default="fixed"):
|
||||
gtk.GtkHBox.__init__(self, gtk.FALSE, 5)
|
||||
self.entry = gtk.GtkEntry()
|
||||
self.pack_start(self.entry)
|
||||
self.entry.show()
|
||||
self.button = gtk.GtkButton("...")
|
||||
self.button.connect("clicked", self.show_dialog)
|
||||
self.pack_start(self.button, expand=gtk.FALSE)
|
||||
self.button.show()
|
||||
|
||||
self.dialog = gtk.GtkFontSelectionDialog("Fonts")
|
||||
self.dialog.set_default_size(400, 300)
|
||||
def delete_event(win, event):
|
||||
win.hide()
|
||||
return gtk.TRUE
|
||||
self.dialog.connect("delete_event", delete_event)
|
||||
|
||||
self.dialog.ok_button.connect("clicked", self.selection_ok)
|
||||
self.dialog.cancel_button.connect("clicked", self.dialog.hide)
|
||||
|
||||
self.dialog.set_font_name(default)
|
||||
self.selected = default
|
||||
self.entry.set_text(self.selected)
|
||||
|
||||
def show_dialog(self, button):
|
||||
self.dialog.show()
|
||||
|
||||
def selection_ok(self, button):
|
||||
self.dialog.hide()
|
||||
self.selected = self.dialog.get_font_name()
|
||||
self.entry.set_text(self.selected)
|
||||
|
||||
def get_value(self):
|
||||
return self.selected
|
||||
|
||||
class FileSelector(gtk.GtkHBox):
|
||||
def __init__(self, default=""):
|
||||
gtk.GtkHBox.__init__(self, gtk.FALSE, 5)
|
||||
self.entry = gtk.GtkEntry()
|
||||
self.pack_start(self.entry)
|
||||
self.entry.show()
|
||||
self.button = gtk.GtkButton("...")
|
||||
self.button.connect("clicked", self.show_dialog)
|
||||
self.pack_start(self.button, expand=gtk.FALSE)
|
||||
self.button.show()
|
||||
|
||||
self.dialog = gtk.GtkFileSelection("Fonts")
|
||||
self.dialog.set_default_size(400, 300)
|
||||
def delete_event(win, event):
|
||||
win.hide()
|
||||
return gtk.TRUE
|
||||
self.dialog.connect("delete_event", delete_event)
|
||||
|
||||
self.dialog.ok_button.connect("clicked", self.selection_ok)
|
||||
self.dialog.cancel_button.connect("clicked", self.dialog.hide)
|
||||
|
||||
self.dialog.set_filename(default)
|
||||
self.selected = self.dialog.get_filename()
|
||||
self.entry.set_text(self.selected)
|
||||
|
||||
def show_dialog(self, button):
|
||||
self.dialog.show()
|
||||
|
||||
def selection_ok(self, button):
|
||||
self.dialog.hide()
|
||||
self.selected = self.dialog.get_filename()
|
||||
self.entry.set_text(self.selected)
|
||||
|
||||
def get_value(self):
|
||||
return self.selected
|
5
plug-ins/pygimp/plug-ins/.cvsignore
Normal file
5
plug-ins/pygimp/plug-ins/.cvsignore
Normal file
@ -0,0 +1,5 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
*.pyc
|
||||
*.pyo
|
||||
|
7
plug-ins/pygimp/plug-ins/Makefile.am
Normal file
7
plug-ins/pygimp/plug-ins/Makefile.am
Normal file
@ -0,0 +1,7 @@
|
||||
pluginexec_SCRIPTS = clothify.py gimpcons.py pdbbrowse.py sphere.py \
|
||||
whirlpinch.py foggify.py shadow_bevel.py
|
||||
|
||||
pluginexec_DATA = gtkcons.py
|
||||
|
||||
EXTRA_DIST = clothify.py gimpcons.py pdbbrowse.py sphere.py gtkcons.py \
|
||||
whirlpinch.py foggify.py shadow_bevel.py
|
74
plug-ins/pygimp/plug-ins/clothify.py
Executable file
74
plug-ins/pygimp/plug-ins/clothify.py
Executable file
@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Gimp-Python - allows the writing of Gimp plugins in Python.
|
||||
# Copyright (C) 1997 James Henstridge <james@daa.com.au>
|
||||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
import math
|
||||
from gimpfu import *
|
||||
|
||||
have_gimp11 = gimp.major_version > 1 or \
|
||||
gimp.major_version == 1 and gimp.minor_version >= 1
|
||||
|
||||
def python_clothify(timg, tdrawable, bx=9, by=9,
|
||||
azimuth=135, elevation=45, depth=3):
|
||||
bx = 9 ; by = 9 ; azimuth = 135 ; elevation = 45 ; depth = 3
|
||||
width = tdrawable.width
|
||||
height = tdrawable.height
|
||||
img = gimp.image(width, height, RGB)
|
||||
layer_one = gimp.layer(img, "X Dots", width, height, RGB_IMAGE,
|
||||
100, NORMAL_MODE)
|
||||
img.disable_undo()
|
||||
if have_gimp11:
|
||||
pdb.gimp_edit_fill(layer_one)
|
||||
else:
|
||||
pdb.gimp_edit_fill(img, layer_one)
|
||||
img.add_layer(layer_one, 0)
|
||||
pdb.plug_in_noisify(img, layer_one, 0, 0.7, 0.7, 0.7, 0.7)
|
||||
layer_two = layer_one.copy()
|
||||
layer_two.mode = MULTIPLY_MODE
|
||||
layer_two.name = "Y Dots"
|
||||
img.add_layer(layer_two, 0)
|
||||
pdb.plug_in_gauss_rle(img, layer_one, bx, 1, 0)
|
||||
pdb.plug_in_gauss_rle(img, layer_two, by, 0, 1)
|
||||
img.flatten()
|
||||
bump_layer = img.active_layer
|
||||
pdb.plug_in_c_astretch(img, bump_layer)
|
||||
pdb.plug_in_noisify(img, bump_layer, 0, 0.2, 0.2, 0.2, 0.2)
|
||||
pdb.plug_in_bump_map(img, tdrawable, bump_layer, azimuth,
|
||||
elevation, depth, 0, 0, 0, 0, TRUE, FALSE, 0)
|
||||
gimp.delete(img)
|
||||
|
||||
register(
|
||||
"python_fu_clothify",
|
||||
"Make the specified layer look like it is printed on cloth",
|
||||
"Make the specified layer look like it is printed on cloth",
|
||||
"James Henstridge",
|
||||
"James Henstridge",
|
||||
"1997-1999",
|
||||
"<Image>/Python-Fu/Alchemy/Clothify",
|
||||
"RGB*, GRAY*",
|
||||
[
|
||||
(PF_INT, "x_blur", "X Blur", 9),
|
||||
(PF_INT, "y_blur", "Y Blur", 9),
|
||||
(PF_INT, "azimuth", "Azimuth", 135),
|
||||
(PF_INT, "elevation", "elevation", 45),
|
||||
(PF_INT, "depth", "Depth", 3)
|
||||
],
|
||||
[],
|
||||
python_clothify)
|
||||
|
||||
main()
|
54
plug-ins/pygimp/plug-ins/foggify.py
Executable file
54
plug-ins/pygimp/plug-ins/foggify.py
Executable file
@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from gimpfu import *
|
||||
import time
|
||||
|
||||
have_gimp11 = gimp.major_version > 1 or \
|
||||
gimp.major_version == 1 and gimp.minor_version >= 1
|
||||
|
||||
def python_foggify(img, layer, name, colour, turbulence, opacity):
|
||||
img.disable_undo()
|
||||
|
||||
fog = gimp.layer(img, name, layer.width, layer.height, RGBA_IMAGE,
|
||||
opacity, NORMAL_MODE)
|
||||
oldbg = gimp.get_background()
|
||||
gimp.set_background(colour)
|
||||
if have_gimp11:
|
||||
pdb.gimp_edit_fill(fog)
|
||||
else:
|
||||
pdb.gimp_edit_fill(img, fog)
|
||||
gimp.set_background(oldbg)
|
||||
|
||||
img.add_layer(fog, 0)
|
||||
|
||||
# create a layer mask for the new layer
|
||||
mask = fog.create_mask(0)
|
||||
img.add_layer_mask(fog, mask)
|
||||
|
||||
# add some clouds to the layer
|
||||
pdb.plug_in_plasma(img, mask, int(time.time()), turbulence)
|
||||
|
||||
# apply the clouds to the layer
|
||||
img.remove_layer_mask(fog, APPLY)
|
||||
|
||||
img.enable_undo()
|
||||
|
||||
register(
|
||||
"python_fu_foggify",
|
||||
"Add a layer of fog to the image",
|
||||
"Add a layer of fog to the image",
|
||||
"James Henstridge",
|
||||
"James Henstridge",
|
||||
"1999",
|
||||
"<Image>/Python-Fu/Effects/Add fog",
|
||||
"RGB*, GRAY*",
|
||||
[
|
||||
(PF_STRING, "name", "The new layer name", "Clouds"),
|
||||
(PF_COLOUR, "colour", "The colour of the fog", (240,180,70)),
|
||||
(PF_SLIDER, "turbulence", "The turbulence", 1.0, (0, 10, 0.1)),
|
||||
(PF_SLIDER, "opacity", "The opacity", 100, (0, 100, 1)),
|
||||
],
|
||||
[],
|
||||
python_foggify)
|
||||
|
||||
main()
|
81
plug-ins/pygimp/plug-ins/gimpcons.py
Executable file
81
plug-ins/pygimp/plug-ins/gimpcons.py
Executable file
@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Gimp-Python - allows the writing of Gimp plugins in Python.
|
||||
# Copyright (C) 1997 James Henstridge <james@daa.com.au>
|
||||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
from gimpfu import *
|
||||
import gtkcons
|
||||
|
||||
def extension_python_fu_console():
|
||||
import gtk, gimpenums, gimpshelf
|
||||
gtk.rc_parse(gimp.gtkrc())
|
||||
namespace = {'__builtins__': __builtins__,
|
||||
'__name__': '__main__', '__doc__': None,
|
||||
'gimp': gimp, 'pdb': gimp.pdb,
|
||||
'shelf': gimpshelf.shelf}
|
||||
for s in gimpenums.__dict__.keys():
|
||||
if s[0] != '_':
|
||||
namespace[s] = getattr(gimpenums, s)
|
||||
|
||||
win = gtk.GtkWindow()
|
||||
win.connect("destroy", gtk.mainquit)
|
||||
win.set_title("Gimp-Python Console")
|
||||
cons = gtkcons.Console(namespace=namespace,
|
||||
copyright='Gimp Python Extensions - Copyright (C), 1997-1999' +
|
||||
' James Henstridge\n', quit_cb=gtk.mainquit)
|
||||
|
||||
def browse(button, cons):
|
||||
import gtk, pdbbrowse
|
||||
def ok_clicked(button, browse, cons=cons):
|
||||
cons.line.set_text(browse.cmd)
|
||||
browse.destroy()
|
||||
win = pdbbrowse.BrowseWin(ok_button=ok_clicked)
|
||||
win.connect("destroy", gtk.mainquit)
|
||||
win.set_modal(TRUE)
|
||||
win.show()
|
||||
gtk.mainloop()
|
||||
button = gtk.GtkButton("Browse")
|
||||
button.connect("clicked", browse, cons)
|
||||
cons.inputbox.pack_end(button, expand=FALSE)
|
||||
button.show()
|
||||
win.add(cons)
|
||||
cons.show()
|
||||
win.set_default_size(475, 300)
|
||||
win.show()
|
||||
cons.init()
|
||||
# flush the displays every half second
|
||||
def timeout():
|
||||
gimp.displays_flush()
|
||||
return TRUE
|
||||
gtk.timeout_add(500, timeout)
|
||||
gtk.mainloop()
|
||||
|
||||
register(
|
||||
"python_fu_console",
|
||||
"Python interactive interpreter with gimp extensions",
|
||||
"Type in commands and see results",
|
||||
"James Henstridge",
|
||||
"James Henstridge",
|
||||
"1997-1999",
|
||||
"<Toolbox>/Xtns/Python-Fu/Console",
|
||||
"*",
|
||||
[],
|
||||
[],
|
||||
extension_python_fu_console)
|
||||
|
||||
main()
|
||||
|
330
plug-ins/pygimp/plug-ins/gtkcons.py
Executable file
330
plug-ins/pygimp/plug-ins/gtkcons.py
Executable file
@ -0,0 +1,330 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Interactive Python-GTK Console
|
||||
# Copyright (C), 1998 James Henstridge <james@daa.com.au>
|
||||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
# This module implements an interactive python session in a GTK window. To
|
||||
# start the session, use the gtk_console command. Its specification is:
|
||||
# gtk_console(namespace, title, copyright)
|
||||
# where namespace is a dictionary representing the namespace of the session,
|
||||
# title is the title on the window and
|
||||
# copyright is any additional copyright info to print.
|
||||
#
|
||||
# As well as the starting attributes in namespace, the session will also
|
||||
# have access to the list __history__, which is the command history.
|
||||
|
||||
import sys, string, traceback
|
||||
#sys.path.append('/home/james/.gimp/plug-ins')
|
||||
from gtk import *
|
||||
|
||||
stdout = sys.stdout
|
||||
|
||||
if not hasattr(sys, 'ps1'): sys.ps1 = '>>> '
|
||||
if not hasattr(sys, 'ps2'): sys.ps2 = '... '
|
||||
|
||||
# some functions to help recognise breaks between commands
|
||||
def remQuotStr(s):
|
||||
'''Returns s with any quoted strings removed (leaving quote marks)'''
|
||||
r = ''
|
||||
inq = 0
|
||||
qt = ''
|
||||
prev = '_'
|
||||
while len(s):
|
||||
s0, s = s[0], s[1:]
|
||||
if inq and (s0 != qt or prev == '\\'):
|
||||
prev = s0
|
||||
continue
|
||||
prev = s0
|
||||
if s0 in '\'"':
|
||||
if inq:
|
||||
inq = 0
|
||||
else:
|
||||
inq = 1
|
||||
qt = s0
|
||||
r = r + s0
|
||||
return r
|
||||
|
||||
def bracketsBalanced(s):
|
||||
'''Returns true iff the brackets in s are balanced'''
|
||||
s = filter(lambda x: x in '()[]{}', s)
|
||||
stack = []
|
||||
brackets = {'(':')', '[':']', '{':'}'}
|
||||
while len(s) != 0:
|
||||
if s[0] in ")]}":
|
||||
if len(stack) != 0 and brackets[stack[-1]] == s[0]:
|
||||
del stack[-1]
|
||||
else:
|
||||
return 0
|
||||
else:
|
||||
stack.append(s[0])
|
||||
s = s[1:]
|
||||
return len(stack) == 0
|
||||
|
||||
class gtkoutfile:
|
||||
'''A fake output file object. It sends output to a TK test widget,
|
||||
and if asked for a file number, returns one set on instance creation'''
|
||||
def __init__(self, w, fn, font):
|
||||
self.__fn = fn
|
||||
self.__w = w
|
||||
self.__font = font
|
||||
def close(self): pass
|
||||
flush = close
|
||||
def fileno(self): return self.__fn
|
||||
def isatty(self): return 0
|
||||
def read(self, a): return ''
|
||||
def readline(self): return ''
|
||||
def readlines(self): return []
|
||||
def write(self, s):
|
||||
#stdout.write(str(self.__w.get_point()) + '\n')
|
||||
self.__w.freeze()
|
||||
self.__w.insert(self.__font, self.__w.fg,
|
||||
self.__w.bg, s)
|
||||
self.__w.thaw()
|
||||
self.__w.queue_draw()
|
||||
def writelines(self, l):
|
||||
self.__w.freeze()
|
||||
for s in l: self.__w.insert(self.__font,
|
||||
self.__w.fg, self.__w.bg, s)
|
||||
self.__w.thaw()
|
||||
self.__w.queue_draw()
|
||||
def seek(self, a): raise IOError, (29, 'Illegal seek')
|
||||
def tell(self): raise IOError, (29, 'Illegal seek')
|
||||
truncate = tell
|
||||
|
||||
class Console(GtkVBox):
|
||||
def __init__(self, namespace={}, copyright='', quit_cb=None):
|
||||
GtkVBox.__init__(self, spacing=2)
|
||||
self.set_border_width(2)
|
||||
self.copyright = copyright
|
||||
#self.set_usize(475, 300)
|
||||
|
||||
self.quit_cb = quit_cb
|
||||
|
||||
#load the fonts we will use
|
||||
self.normal = load_font(
|
||||
"-*-helvetica-medium-r-normal-*-*-100-*-*-*-*-*-*")
|
||||
self.title = load_font(
|
||||
"-*-helvetica-bold-r-normal-*-*-100-*-*-*-*-*-*")
|
||||
self.error = load_font(
|
||||
"-*-helvetica-medium-o-normal-*-12-100-*-*-*-*-*-*")
|
||||
self.command = load_font(
|
||||
"-*-helvetica-bold-r-normal-*-*-100-*-*-*-*-*-*")
|
||||
|
||||
self.inp = GtkHBox()
|
||||
self.pack_start(self.inp)
|
||||
self.inp.show()
|
||||
|
||||
self.text = GtkText()
|
||||
self.text.set_editable(FALSE)
|
||||
self.text.set_word_wrap(TRUE)
|
||||
self.text.set_usize(500, 400)
|
||||
self.inp.pack_start(self.text, padding=1)
|
||||
self.text.show()
|
||||
|
||||
self.vscroll = GtkVScrollbar(self.text.get_vadjustment())
|
||||
self.vscroll.set_update_policy(POLICY_AUTOMATIC)
|
||||
self.inp.pack_end(self.vscroll, expand=FALSE)
|
||||
self.vscroll.show()
|
||||
|
||||
self.inputbox = GtkHBox(spacing=2)
|
||||
self.pack_end(self.inputbox, expand=FALSE)
|
||||
self.inputbox.show()
|
||||
|
||||
self.prompt = GtkLabel(sys.ps1)
|
||||
self.prompt.set_padding(xp=2, yp=0)
|
||||
self.prompt.set_usize(26, -1)
|
||||
self.inputbox.pack_start(self.prompt, fill=FALSE, expand=FALSE)
|
||||
self.prompt.show()
|
||||
|
||||
self.closer = GtkButton("Close")
|
||||
self.closer.connect("clicked", self.quit)
|
||||
self.inputbox.pack_end(self.closer, fill=FALSE, expand=FALSE)
|
||||
self.closer.show()
|
||||
|
||||
self.line = GtkEntry()
|
||||
self.line.set_usize(400,-1)
|
||||
self.line.connect("key_press_event", self.key_function)
|
||||
self.inputbox.pack_start(self.line, padding=2)
|
||||
self.line.show()
|
||||
|
||||
# now let the text box be resized
|
||||
self.text.set_usize(0, 0)
|
||||
self.line.set_usize(0, -1)
|
||||
|
||||
self.namespace = namespace
|
||||
|
||||
self.cmd = ''
|
||||
self.cmd2 = ''
|
||||
|
||||
# set up hooks for standard output.
|
||||
self.stdout = gtkoutfile(self.text, sys.stdout.fileno(),
|
||||
self.normal)
|
||||
self.stderr = gtkoutfile(self.text, sys.stderr.fileno(),
|
||||
self.error)
|
||||
|
||||
# set up command history
|
||||
self.history = ['']
|
||||
self.histpos = 0
|
||||
self.namespace['__history__'] = self.history
|
||||
|
||||
def init(self):
|
||||
self.text.realize()
|
||||
self.text.style = self.text.get_style()
|
||||
self.text.fg = self.text.style.fg[STATE_NORMAL]
|
||||
self.text.bg = self.text.style.white
|
||||
|
||||
self.text.insert(self.title, self.text.fg,
|
||||
self.text.bg, 'Python %s\n%s\n\n' %
|
||||
(sys.version, sys.copyright) +
|
||||
'Interactive Python-GTK Console - ' +
|
||||
'Copyright (C) 1998 James Henstridge\n\n' +
|
||||
self.copyright + '\n')
|
||||
self.line.grab_focus()
|
||||
|
||||
def quit(self, *args):
|
||||
self.hide()
|
||||
self.destroy()
|
||||
if self.quit_cb: self.quit_cb()
|
||||
|
||||
def key_function(self, entry, event):
|
||||
if event.keyval == GDK.Return:
|
||||
self.line.emit_stop_by_name("key_press_event")
|
||||
self.eval()
|
||||
if event.keyval == GDK.Tab:
|
||||
self.line.emit_stop_by_name("key_press_event")
|
||||
self.line.append_text('\t')
|
||||
idle_add(self.focus_text)
|
||||
elif event.keyval in (GDK.KP_Up, GDK.Up):
|
||||
self.line.emit_stop_by_name("key_press_event")
|
||||
self.historyUp()
|
||||
idle_add(self.focus_text)
|
||||
elif event.keyval in (GDK.KP_Down, GDK.Down):
|
||||
self.line.emit_stop_by_name("key_press_event")
|
||||
self.historyDown()
|
||||
idle_add(self.focus_text)
|
||||
elif event.keyval in (GDK.D, GDK.d) and \
|
||||
event.state & GDK.CONTROL_MASK:
|
||||
self.line.emit_stop_by_name("key_press_event")
|
||||
self.ctrld()
|
||||
|
||||
def focus_text(self):
|
||||
self.line.grab_focus()
|
||||
return FALSE # don't requeue this handler
|
||||
|
||||
def ctrld(self):
|
||||
#self.quit()
|
||||
pass
|
||||
|
||||
def historyUp(self):
|
||||
if self.histpos > 0:
|
||||
l = self.line.get_text()
|
||||
if len(l) > 0 and l[0] == '\n': l = l[1:]
|
||||
if len(l) > 0 and l[-1] == '\n': l = l[:-1]
|
||||
self.history[self.histpos] = l
|
||||
self.histpos = self.histpos - 1
|
||||
self.line.set_text(self.history[self.histpos])
|
||||
|
||||
def historyDown(self):
|
||||
if self.histpos < len(self.history) - 1:
|
||||
l = self.line.get_text()
|
||||
if len(l) > 0 and l[0] == '\n': l = l[1:]
|
||||
if len(l) > 0 and l[-1] == '\n': l = l[:-1]
|
||||
self.history[self.histpos] = l
|
||||
self.histpos = self.histpos + 1
|
||||
self.line.set_text(self.history[self.histpos])
|
||||
|
||||
def eval(self):
|
||||
l = self.line.get_text() + '\n'
|
||||
if len(l) > 1 and l[0] == '\n': l = l[1:]
|
||||
self.histpos = len(self.history) - 1
|
||||
if len(l) > 0 and l[-1] == '\n':
|
||||
self.history[self.histpos] = l[:-1]
|
||||
else:
|
||||
self.history[self.histpos] = l
|
||||
self.line.set_text('')
|
||||
self.text.freeze()
|
||||
self.text.insert(self.command, self.text.fg, self.text.bg,
|
||||
self.prompt.get() + l)
|
||||
self.text.thaw()
|
||||
if l == '\n':
|
||||
self.run(self.cmd)
|
||||
self.cmd = ''
|
||||
self.cmd2 = ''
|
||||
return
|
||||
self.histpos = self.histpos + 1
|
||||
self.history.append('')
|
||||
self.cmd = self.cmd + l
|
||||
self.cmd2 = self.cmd2 + remQuotStr(l)
|
||||
l = string.rstrip(l)
|
||||
if not bracketsBalanced(self.cmd2) or l[-1] == ':' or \
|
||||
l[-1] == '\\' or l[0] in ' \11':
|
||||
self.prompt.set_text(sys.ps2)
|
||||
self.prompt.queue_draw()
|
||||
return
|
||||
self.run(self.cmd)
|
||||
self.cmd = ''
|
||||
self.cmd2 = ''
|
||||
|
||||
def run(self, cmd):
|
||||
sys.stdout, self.stdout = self.stdout, sys.stdout
|
||||
sys.stderr, self.stderr = self.stderr, sys.stderr
|
||||
try:
|
||||
try:
|
||||
r = eval(cmd, self.namespace, self.namespace)
|
||||
if r is not None:
|
||||
print `r`
|
||||
except SyntaxError:
|
||||
exec cmd in self.namespace
|
||||
except:
|
||||
if hasattr(sys, 'last_type') and \
|
||||
sys.last_type == SystemExit:
|
||||
self.quit()
|
||||
else:
|
||||
traceback.print_exc()
|
||||
self.prompt.set_text(sys.ps1)
|
||||
self.prompt.queue_draw()
|
||||
adj = self.text.get_vadjustment()
|
||||
adj.set_value(adj.upper - adj.page_size)
|
||||
sys.stdout, self.stdout = self.stdout, sys.stdout
|
||||
sys.stderr, self.stderr = self.stderr, sys.stderr
|
||||
|
||||
def gtk_console(ns, title='Python', copyright='', menu=None):
|
||||
win = GtkWindow()
|
||||
win.set_usize(475, 300)
|
||||
win.connect("destroy", mainquit)
|
||||
win.connect("delete_event", mainquit)
|
||||
win.set_title(title)
|
||||
cons = Console(namespace=ns, copyright=copyright, quit_cb=mainquit)
|
||||
if menu:
|
||||
box = GtkVBox()
|
||||
win.add(box)
|
||||
box.show()
|
||||
box.pack_start(menu, expand=FALSE)
|
||||
menu.show()
|
||||
box.pack_start(cons)
|
||||
else:
|
||||
win.add(cons)
|
||||
cons.show()
|
||||
win.show()
|
||||
win.set_usize(0,0)
|
||||
cons.init()
|
||||
mainloop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
gtk_console({'__builtins__': __builtins__, '__name__': '__main__',
|
||||
'__doc__': None})
|
||||
|
307
plug-ins/pygimp/plug-ins/pdbbrowse.py
Executable file
307
plug-ins/pygimp/plug-ins/pdbbrowse.py
Executable file
@ -0,0 +1,307 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# Gimp-Python - allows the writing of Gimp plugins in Python.
|
||||
# Copyright (C) 1997 James Henstridge <james@daa.com.au>
|
||||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
from gimpfu import *
|
||||
import gimpenums
|
||||
import gtk
|
||||
import string
|
||||
|
||||
pars = filter(lambda x: x[:6] == 'PARAM_', dir(gimpenums))
|
||||
partypes = [''] * len(pars)
|
||||
for i in pars:
|
||||
partypes[gimpenums.__dict__[i]] = i[6:]
|
||||
del pars, i
|
||||
|
||||
class BrowseWin(gtk.GtkWindow):
|
||||
def __init__(self, ok_button=None):
|
||||
gtk.GtkWindow.__init__(self)
|
||||
self.set_title("PDB Browser")
|
||||
|
||||
vbox = gtk.GtkVBox(FALSE, 5)
|
||||
vbox.set_border_width(2)
|
||||
self.add(vbox)
|
||||
vbox.show()
|
||||
|
||||
paned = gtk.GtkHPaned()
|
||||
vbox.pack_start(paned)
|
||||
paned.show()
|
||||
|
||||
listsw = gtk.GtkScrolledWindow()
|
||||
listsw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||
paned.add1(listsw)
|
||||
listsw.show()
|
||||
|
||||
self.list = gtk.GtkCList(1)
|
||||
self.list.set_column_auto_resize(0, TRUE)
|
||||
self.list.set_selection_mode(gtk.SELECTION_BROWSE)
|
||||
listsw.add(self.list)
|
||||
self.list.show()
|
||||
self.update_list()
|
||||
self.list.connect("select_row", self.display)
|
||||
|
||||
self.infosw = gtk.GtkScrolledWindow()
|
||||
self.infosw.set_policy(gtk.POLICY_AUTOMATIC,
|
||||
gtk.POLICY_AUTOMATIC)
|
||||
paned.add2(self.infosw)
|
||||
self.infosw.show()
|
||||
|
||||
self.info = None
|
||||
|
||||
paned.set_position(150)
|
||||
self.cmd = None
|
||||
self.display(self.list, 0, -1, None)
|
||||
|
||||
hbox = gtk.GtkHBox(FALSE, 5)
|
||||
vbox.pack_start(hbox, expand=FALSE)
|
||||
hbox.show()
|
||||
|
||||
entry = gtk.GtkEntry()
|
||||
hbox.pack_start(entry, expand=FALSE)
|
||||
entry.show()
|
||||
|
||||
button = gtk.GtkButton("Search by Name")
|
||||
button.connect("clicked", self.search_name, entry)
|
||||
hbox.pack_start(button, expand=FALSE)
|
||||
button.show()
|
||||
|
||||
button = gtk.GtkButton("Search by Blurb")
|
||||
button.connect("clicked", self.search_blurb, entry)
|
||||
hbox.pack_start(button, expand=FALSE)
|
||||
button.show()
|
||||
|
||||
button = gtk.GtkButton("Close")
|
||||
button.connect("clicked", self.destroy)
|
||||
hbox.pack_end(button, expand=FALSE)
|
||||
button.show()
|
||||
|
||||
if ok_button:
|
||||
button = gtk.GtkButton("OK")
|
||||
button.connect("clicked", ok_button, self)
|
||||
hbox.pack_end(button, expand=FALSE)
|
||||
button.show()
|
||||
|
||||
self.set_default_size(500, 300)
|
||||
|
||||
def search_name(self, button, entry):
|
||||
self.update_list(name=entry.get_text())
|
||||
def search_blurb(self, button, entry):
|
||||
self.update_list(blurb=entry.get_text())
|
||||
|
||||
def update_list(self, name='.*', blurb='.*'):
|
||||
self.pdblist = pdb.query(name,blurb,'.*','.*','.*','.*','.*')
|
||||
self.pdblist.sort()
|
||||
self.list.clear()
|
||||
for item in self.pdblist:
|
||||
self.list.append([item])
|
||||
|
||||
def display(self, clist, row, column, event):
|
||||
proc = pdb[clist.get_text(row, 0)]
|
||||
self.info = gtk.GtkTable(1, 5, FALSE);
|
||||
row = 0
|
||||
label = gtk.GtkLabel("Name:")
|
||||
label.set_alignment(1.0, 0.5)
|
||||
self.info.attach(label, 0,1, row,row+1,
|
||||
xoptions=gtk.FILL, yoptions=gtk.FILL)
|
||||
label.show()
|
||||
|
||||
label = gtk.GtkEntry()
|
||||
label.set_text(proc.proc_name)
|
||||
label.set_editable(FALSE)
|
||||
self.info.attach(label, 1,4, row,row+1,
|
||||
xoptions=gtk.FILL, yoptions=gtk.FILL)
|
||||
label.show()
|
||||
row = row + 1
|
||||
|
||||
label = gtk.GtkLabel("Blurb:")
|
||||
label.set_alignment(1.0, 0.5)
|
||||
self.info.attach(label, 0,1, row,row+1,
|
||||
xoptions=gtk.FILL, yoptions=gtk.FILL)
|
||||
label.show()
|
||||
|
||||
label = gtk.GtkLabel(proc.proc_blurb)
|
||||
label.set_alignment(0.0, 0.5)
|
||||
self.info.attach(label, 1,4, row,row+1,
|
||||
yoptions=gtk.FILL)
|
||||
label.show()
|
||||
row = row + 1
|
||||
|
||||
label = gtk.GtkLabel("Copyright:")
|
||||
label.set_alignment(1.0, 0.5)
|
||||
self.info.attach(label, 0,1, row,row+1,
|
||||
xoptions=gtk.FILL, yoptions=gtk.FILL)
|
||||
label.show()
|
||||
|
||||
label = gtk.GtkLabel(proc.proc_date+", "+proc.proc_copyright)
|
||||
label.set_alignment(0.0, 0.5)
|
||||
self.info.attach(label, 1,4, row,row+1,
|
||||
yoptions=gtk.FILL)
|
||||
label.show()
|
||||
row = row + 1
|
||||
|
||||
label = gtk.GtkLabel("Author:")
|
||||
label.set_alignment(1.0, 0.5)
|
||||
self.info.attach(label, 0,1, row,row+1,
|
||||
xoptions=gtk.FILL, yoptions=gtk.FILL)
|
||||
label.show()
|
||||
|
||||
label = gtk.GtkLabel(proc.proc_author)
|
||||
label.set_alignment(0.0, 0.5)
|
||||
self.info.attach(label, 1,4, row,row+1,
|
||||
yoptions=gtk.FILL)
|
||||
label.show()
|
||||
row = row + 1
|
||||
|
||||
hsep = gtk.GtkHSeparator()
|
||||
self.info.attach(hsep, 0,4, row,row+1,
|
||||
yoptions=gtk.FILL)
|
||||
hsep.show()
|
||||
row = row + 1
|
||||
|
||||
if len(proc.params) > 0:
|
||||
label = gtk.GtkLabel("In:")
|
||||
label.set_alignment(1.0, 0.5)
|
||||
self.info.attach(label, 0,1, row,row+len(proc.params),
|
||||
xoptions=gtk.FILL, yoptions=gtk.FILL)
|
||||
label.show()
|
||||
for tp, name, desc in proc.params:
|
||||
label = gtk.GtkLabel(name)
|
||||
label.set_alignment(0.0, 0.5)
|
||||
self.info.attach(label, 1,2, row,row+1,
|
||||
xoptions=gtk.FILL,
|
||||
yoptions=gtk.FILL)
|
||||
label.show()
|
||||
|
||||
label = gtk.GtkLabel(partypes[tp])
|
||||
label.set_alignment(0.0, 0.5)
|
||||
self.info.attach(label, 2,3, row,row+1,
|
||||
xoptions=gtk.FILL,
|
||||
yoptions=gtk.FILL)
|
||||
label.show()
|
||||
|
||||
label = gtk.GtkLabel(desc)
|
||||
label.set_alignment(0.0, 0.5)
|
||||
self.info.attach(label, 3,4, row,row+1,
|
||||
yoptions=gtk.FILL)
|
||||
label.show()
|
||||
row = row + 1
|
||||
hsep = gtk.GtkHSeparator()
|
||||
self.info.attach(hsep, 0,4, row,row+1,
|
||||
yoptions=gtk.FILL)
|
||||
hsep.show()
|
||||
row = row + 1
|
||||
|
||||
if len(proc.return_vals) > 0:
|
||||
label = gtk.GtkLabel("Out:")
|
||||
label.set_alignment(1.0, 0.5)
|
||||
self.info.attach(label, 0,1,
|
||||
row,row+len(proc.return_vals),
|
||||
xoptions=gtk.FILL, yoptions=gtk.FILL)
|
||||
label.show()
|
||||
for tp, name, desc in proc.return_vals:
|
||||
label = gtk.GtkLabel(name)
|
||||
label.set_alignment(0.0, 0.5)
|
||||
self.info.attach(label, 1,2, row,row+1,
|
||||
xoptions=gtk.FILL,
|
||||
yoptions=gtk.FILL)
|
||||
label.show()
|
||||
|
||||
label = gtk.GtkLabel(partypes[tp])
|
||||
label.set_alignment(0.0, 0.5)
|
||||
self.info.attach(label, 2,3, row,row+1,
|
||||
xoptions=gtk.FILL,
|
||||
yoptions=gtk.FILL)
|
||||
label.show()
|
||||
|
||||
label = gtk.GtkLabel(desc)
|
||||
label.set_alignment(0.0, 0.5)
|
||||
self.info.attach(label, 3,4, row,row+1,
|
||||
yoptions=gtk.FILL)
|
||||
label.show()
|
||||
row = row + 1
|
||||
hsep = gtk.GtkHSeparator()
|
||||
self.info.attach(hsep, 0,4, row,row+1,
|
||||
yoptions=gtk.FILL)
|
||||
hsep.show()
|
||||
row = row + 1
|
||||
|
||||
label = gtk.GtkLabel("Help:")
|
||||
label.set_alignment(1.0, 0.5)
|
||||
self.info.attach(label, 0,1, row,row+1,
|
||||
xoptions=gtk.FILL, yoptions=gtk.FILL)
|
||||
label.show()
|
||||
|
||||
label = gtk.GtkLabel(proc.proc_help)
|
||||
label.set_alignment(0.0, 0.5)
|
||||
label.set_justify(gtk.JUSTIFY_LEFT)
|
||||
label.set_line_wrap(TRUE)
|
||||
label.set_usize(300, -1)
|
||||
self.info.attach(label, 1,4, row,row+1,
|
||||
yoptions=gtk.FILL)
|
||||
label.show()
|
||||
row = row + 1
|
||||
|
||||
self.info.set_col_spacings(5)
|
||||
self.info.set_row_spacings(3)
|
||||
self.info.set_border_width(3)
|
||||
|
||||
children = self.infosw.children()
|
||||
if children:
|
||||
self.infosw.remove(children[0])
|
||||
|
||||
self.infosw.add_with_viewport(self.info)
|
||||
self.info.show()
|
||||
|
||||
# now setup the self.cmd
|
||||
self.cmd = ''
|
||||
if len(proc.return_vals) > 0:
|
||||
self.cmd = string.join(
|
||||
map(lambda x: x[1], proc.return_vals), ', ') +\
|
||||
' = '
|
||||
if '-' in proc.proc_name:
|
||||
self.cmd = self.cmd + "pdb['" + proc.proc_name + "']"
|
||||
else:
|
||||
self.cmd = self.cmd + "pdb." + proc.proc_name
|
||||
if len(proc.params) > 0 and proc.params[0][1] == 'run_mode':
|
||||
params = proc.params[1:]
|
||||
else:
|
||||
params = proc.params
|
||||
self.cmd = self.cmd + "(" + string.join(
|
||||
map(lambda x: x[1], params), ', ') + ")"
|
||||
|
||||
if __name__ == '__main__':
|
||||
def extension_pdb_browse():
|
||||
gtk.rc_parse(gimp.gtkrc())
|
||||
win = BrowseWin()
|
||||
win.connect("destroy", gtk.mainquit)
|
||||
win.show()
|
||||
gtk.mainloop()
|
||||
register(
|
||||
"python_fu_pdb_browse",
|
||||
"Browse the Procedural Database",
|
||||
"Pick a PDB proc, and read the information",
|
||||
"James Henstridge",
|
||||
"James Henstridge",
|
||||
"1997-1999",
|
||||
"<Toolbox>/Xtns/Python-Fu/PDB Browser",
|
||||
"*",
|
||||
[],
|
||||
[],
|
||||
extension_pdb_browse)
|
||||
main()
|
||||
|
68
plug-ins/pygimp/plug-ins/shadow_bevel.py
Executable file
68
plug-ins/pygimp/plug-ins/shadow_bevel.py
Executable file
@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from gimpfu import *
|
||||
|
||||
have_gimp11 = gimp.major_version > 1 or gimp.major_version == 1 and \
|
||||
gimp.minor_version >= 1
|
||||
|
||||
def shadow_bevel(img, drawable, blur, bevel, do_shadow, drop_x, drop_y):
|
||||
# disable undo for the image
|
||||
img.disable_undo()
|
||||
|
||||
# copy the layer
|
||||
shadow = drawable.copy(TRUE)
|
||||
img.add_layer(shadow, img.layers.index(drawable)+1)
|
||||
shadow.name = drawable.name + " shadow"
|
||||
shadow.preserve_transparency = FALSE
|
||||
|
||||
# threshold the shadow layer to all white
|
||||
if have_gimp11:
|
||||
pdb.gimp_threshold(shadow, 0, 255)
|
||||
else:
|
||||
pdb.gimp_threshold(img, shadow, 0, 255)
|
||||
|
||||
# blur the shadow layer
|
||||
pdb.plug_in_gauss_iir(img, shadow, blur, TRUE, TRUE)
|
||||
|
||||
# do the bevel thing ...
|
||||
if bevel:
|
||||
pdb.plug_in_bump_map(img, drawable, shadow, 135, 45, 3,
|
||||
0, 0, 0, 0, TRUE, FALSE, 0)
|
||||
|
||||
# make the shadow layer black now ...
|
||||
if have_gimp11:
|
||||
pdb.gimp_invert(shadow)
|
||||
else:
|
||||
pdb.gimp_invert(img, shadow)
|
||||
|
||||
# translate the drop shadow
|
||||
shadow.translate(drop_x, drop_y)
|
||||
|
||||
if not do_shadow:
|
||||
# delete shadow ...
|
||||
gimp.delete(shadow)
|
||||
|
||||
# enable undo again
|
||||
img.enable_undo()
|
||||
|
||||
register(
|
||||
"shadow_bevel",
|
||||
"Add a drop shadow to a layer, and optionally bevel it.",
|
||||
"Add a drop shadow to a layer, and optionally bevel it.",
|
||||
"James Henstridge",
|
||||
"James Henstridge",
|
||||
"1999",
|
||||
"<Image>/Python-Fu/Effects/Drop Shadow and Bevel",
|
||||
"RGBA, GRAYA",
|
||||
[
|
||||
(PF_SLIDER, "blur", "Shadow Blur", 6, (1, 30, 1)),
|
||||
(PF_BOOL, "bevel", "Bevel the image", TRUE),
|
||||
(PF_BOOL, "shadow", "Make a drop shadow", TRUE),
|
||||
(PF_INT, "drop_x", "Drop shadow X displacement", 3),
|
||||
(PF_INT, "drop_y", "Drop shadow Y displacement", 6)
|
||||
],
|
||||
[],
|
||||
shadow_bevel)
|
||||
|
||||
main()
|
||||
|
103
plug-ins/pygimp/plug-ins/sphere.py
Executable file
103
plug-ins/pygimp/plug-ins/sphere.py
Executable file
@ -0,0 +1,103 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# Gimp-Python - allows the writing of Gimp plugins in Python.
|
||||
# Copyright (C) 1997 James Henstridge <james@daa.com.au>
|
||||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
import math
|
||||
from gimpfu import *
|
||||
|
||||
have_gimp11 = gimp.major_version > 1 or \
|
||||
gimp.major_version == 1 and gimp.minor_version >= 1
|
||||
|
||||
def python_sphere(radius, light, shadow, bg_colour, sphere_colour):
|
||||
width = radius * 3.75
|
||||
height = radius * 2.5;
|
||||
img = gimp.image(width, height, RGB)
|
||||
drawable = gimp.layer(img, "Sphere Layer", width, height,
|
||||
RGB_IMAGE, 100, NORMAL_MODE)
|
||||
radians = light * math.pi / 180
|
||||
cx = width / 2
|
||||
cy = height / 2
|
||||
light_x = cx + radius * 0.6 * math.cos(radians)
|
||||
light_y = cy - radius * 0.6 * math.sin(radians)
|
||||
light_end_x = cx + radius * math.cos(math.pi + radians)
|
||||
light_end_y = cy - radius * math.sin(math.pi + radians)
|
||||
offset = radius * 0.1
|
||||
old_fg = gimp.get_foreground()
|
||||
old_bg = gimp.get_background()
|
||||
img.disable_undo()
|
||||
img.add_layer(drawable, 0)
|
||||
gimp.set_foreground(sphere_colour)
|
||||
gimp.set_background(bg_colour)
|
||||
if have_gimp11:
|
||||
pdb.gimp_edit_fill(drawable)
|
||||
else:
|
||||
pdb.gimp_edit_fill(img, drawable)
|
||||
gimp.set_background(20, 20, 20)
|
||||
if (light >= 45 and light <= 75 or light <= 135 and
|
||||
light >= 105) and shadow:
|
||||
shadow_w = radius * 2.5 * math.cos(math.pi + radians)
|
||||
shadow_h = radius * 0.5
|
||||
shadow_x = cx
|
||||
shadow_y = cy + radius * 0.65
|
||||
if shadow_w < 0:
|
||||
shadow_x = cx + shadow_w
|
||||
shadow_w = -shadow_w
|
||||
pdb.gimp_ellipse_select(img, shadow_x, shadow_y,
|
||||
shadow_w, shadow_h, REPLACE, 1, 1, 7.5)
|
||||
if have_gimp11:
|
||||
pdb.gimp_bucket_fill(drawable, BG_BUCKET_FILL,
|
||||
MULTIPLY_MODE, 100, 0, 0, 0, 0)
|
||||
else:
|
||||
pdb.gimp_bucket_fill(img, drawable, BG_BUCKET_FILL,
|
||||
MULTIPLY_MODE, 100, 0, 0, 0, 0)
|
||||
pdb.gimp_ellipse_select(img, cx - radius, cy - radius,
|
||||
2 * radius, 2 * radius, REPLACE, 1, 0, 0)
|
||||
if have_gimp11:
|
||||
pdb.gimp_blend(drawable, FG_BG_RGB, NORMAL_MODE, RADIAL,
|
||||
100, offset, REPEAT_NONE, 0, 0, 0, light_x,
|
||||
light_y, light_end_x, light_end_y)
|
||||
else:
|
||||
pdb.gimp_blend(img, drawable, FG_BG_RGB, NORMAL_MODE, RADIAL,
|
||||
100, offset, REPEAT_NONE, 0, 0, 0, light_x,
|
||||
light_y, light_end_x, light_end_y)
|
||||
pdb.gimp_selection_none(img)
|
||||
gimp.set_background(old_bg)
|
||||
gimp.set_foreground(old_fg)
|
||||
img.enable_undo()
|
||||
disp = gimp.display(img)
|
||||
|
||||
register(
|
||||
"python_fu_sphere",
|
||||
"Simple spheres with drop shadows",
|
||||
"Simple spheres with drop shadows (based on script-fu version)",
|
||||
"James Henstridge",
|
||||
"James Henstridge",
|
||||
"1997-1999",
|
||||
"<Toolbox>/Xtns/Python-Fu/Misc/Sphere",
|
||||
"RGB*, GRAY*, INDEXED*",
|
||||
[
|
||||
(PF_INT, "radius", "Radius for sphere", 100),
|
||||
(PF_SLIDER, "light", "light angle", 45, (0,360,1)),
|
||||
(PF_TOGGLE, "shadow", "shadow?", 1),
|
||||
(PF_COLOR, "bg_colour", "background", (255,255,255)),
|
||||
(PF_COLOR, "sphere_colour", "sphere", (255,0,0))
|
||||
],
|
||||
[],
|
||||
python_sphere)
|
||||
|
||||
main()
|
217
plug-ins/pygimp/plug-ins/whirlpinch.py
Executable file
217
plug-ins/pygimp/plug-ins/whirlpinch.py
Executable file
@ -0,0 +1,217 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Gimp-Python - allows the writing of Gimp plugins in Python.
|
||||
# Copyright (C) 1997 James Henstridge <james@daa.com.au>
|
||||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
# Algorithms stolen from the whirl and pinch plugin distributed with Gimp,
|
||||
# by Federico Mena Quintero and Scott Goehring
|
||||
#
|
||||
# This version does the same thing, except there is no preview, and it is
|
||||
# written in python and is slower.
|
||||
|
||||
import math, struct
|
||||
from gimpfu import *
|
||||
|
||||
class pixel_fetcher:
|
||||
def __init__(self, drawable):
|
||||
self.col = -1
|
||||
self.row = -1
|
||||
self.img_width = drawable.width
|
||||
self.img_height = drawable.height
|
||||
self.img_bpp = drawable.bpp
|
||||
self.img_has_alpha = drawable.has_alpha
|
||||
self.tile_width = 64
|
||||
self.tile_height = 64
|
||||
self.bg_colour = '\0\0\0\0'
|
||||
self.bounds = drawable.mask_bounds
|
||||
self.drawable = drawable
|
||||
self.tile = None
|
||||
def set_bg_colour(self, r, g, b, a):
|
||||
self.bg_colour = struct.pack('bbb', r,g,b)
|
||||
if self.img_has_alpha:
|
||||
self.bg_colour = self.bg_colour + chr(a)
|
||||
def get_pixel(self, x, y):
|
||||
sel_x1, sel_y1, sel_x2, sel_y2 = self.bounds
|
||||
if x < sel_x1 or x >= sel_x2 or y < sel_y1 or y >= sel_y2:
|
||||
return self.bg_colour
|
||||
col = x / self.tile_width
|
||||
coloff = x % self.tile_width
|
||||
row = y / self.tile_height
|
||||
rowoff = y % self.tile_height
|
||||
|
||||
if col != self.col or row != self.row or self.tile == None:
|
||||
self.tile = self.drawable.get_tile(FALSE, row, col)
|
||||
self.col = col
|
||||
self.row = row
|
||||
return self.tile[coloff, rowoff]
|
||||
|
||||
class Dummy:
|
||||
pass
|
||||
|
||||
def python_whirl_pinch(image, drawable, whirl, pinch, radius):
|
||||
self = Dummy()
|
||||
self.width = drawable.width
|
||||
self.height = drawable.height
|
||||
self.bpp = drawable.bpp
|
||||
self.has_alpha = drawable.has_alpha
|
||||
self.bounds = drawable.mask_bounds
|
||||
self.sel_x1, self.sel_y1, self.sel_x2, self.sel_y2 = \
|
||||
drawable.mask_bounds
|
||||
self.sel_w = self.sel_x2 - self.sel_x1
|
||||
self.sel_h = self.sel_y2 - self.sel_y1
|
||||
self.cen_x = (self.sel_x1 + self.sel_x2 - 1) / 2.0
|
||||
self.cen_y = (self.sel_y1 + self.sel_y2 - 1) / 2.0
|
||||
xhsiz = (self.sel_w - 1) / 2.0
|
||||
yhsiz = (self.sel_h - 1) / 2.0
|
||||
|
||||
if xhsiz < yhsiz:
|
||||
self.scale_x = yhsiz / xhsiz
|
||||
self.scale_y = 1.0
|
||||
elif xhsiz > yhsiz:
|
||||
self.scale_x = 1.0
|
||||
self.scale_y = xhsiz / yhsiz
|
||||
else:
|
||||
self.scale_x = 1.0
|
||||
self.scale_y = 1.0
|
||||
|
||||
self.radius = max(xhsiz, yhsiz);
|
||||
|
||||
if not drawable.is_colour and not drawable.is_grey:
|
||||
return
|
||||
|
||||
gimp.tile_cache_ntiles(2 * (self.width + 63) / 64)
|
||||
|
||||
whirl = whirl * math.pi / 180
|
||||
dest_rgn = drawable.get_pixel_rgn(self.sel_x1, self.sel_y1,
|
||||
self.sel_w, self.sel_h, TRUE, TRUE)
|
||||
pft = pixel_fetcher(drawable)
|
||||
pfb = pixel_fetcher(drawable)
|
||||
bg_colour = gimp.get_background()
|
||||
pft.set_bg_colour(bg_colour[0], bg_colour[1], bg_colour[2], 0)
|
||||
pfb.set_bg_colour(bg_colour[0], bg_colour[1], bg_colour[2], 0)
|
||||
progress = 0
|
||||
max_progress = self.sel_w * self.sel_h
|
||||
gimp.progress_init("Whirling and pinching...")
|
||||
self.radius2 = self.radius * self.radius * radius
|
||||
pixel = ['', '', '', '']
|
||||
values = [0,0,0,0]
|
||||
for row in range(self.sel_y1, (self.sel_y1+self.sel_y2)/2+1):
|
||||
top_p = ''
|
||||
bot_p = ''
|
||||
for col in range(self.sel_x1, self.sel_x2):
|
||||
q, cx, cy = calc_undistorted_coords(self, col,
|
||||
row, whirl, pinch, radius)
|
||||
if q:
|
||||
if cx >= 0: ix = int(cx)
|
||||
else: ix = -(int(-cx) + 1)
|
||||
if cy >= 0: iy = int(cy)
|
||||
else: iy = -(int(-cx) + 1)
|
||||
pixel[0] = pft.get_pixel(ix, iy)
|
||||
pixel[1] = pft.get_pixel(ix+1, iy)
|
||||
pixel[2] = pft.get_pixel(ix, iy+1)
|
||||
pixel[3] = pft.get_pixel(ix+1, iy+1)
|
||||
for i in range(self.bpp):
|
||||
values[0] = ord(pixel[0][i])
|
||||
values[1] = ord(pixel[1][i])
|
||||
values[2] = ord(pixel[2][i])
|
||||
values[3] = ord(pixel[3][i])
|
||||
top_p = top_p + bilinear(cx,cy, values)
|
||||
cx = self.cen_x + (self.cen_x - cx)
|
||||
cy = self.cen_y + (self.cen_y - cy)
|
||||
if cx >= 0: ix = int(cx)
|
||||
else: ix = -(int(-cx) + 1)
|
||||
if cy >= 0: iy = int(cy)
|
||||
else: iy = -(int(-cy) + 1)
|
||||
pixel[0] = pfb.get_pixel(ix, iy)
|
||||
pixel[1] = pfb.get_pixel(ix+1, iy)
|
||||
pixel[2] = pfb.get_pixel(ix, iy+1)
|
||||
pixel[3] = pfb.get_pixel(ix+1, iy+1)
|
||||
tmp = ''
|
||||
for i in range(self.bpp):
|
||||
values[0] = ord(pixel[0][i])
|
||||
values[1] = ord(pixel[1][i])
|
||||
values[2] = ord(pixel[2][i])
|
||||
values[3] = ord(pixel[3][i])
|
||||
tmp = tmp + bilinear(cx,cy, values)
|
||||
bot_p = tmp + bot_p
|
||||
else:
|
||||
top_p = top_p + pft.get_pixel(col, row)
|
||||
bot_p = pfb.get_pixel((self.sel_x2 - 1) -
|
||||
(col - self.sel_x1), (self.sel_y2-1) -
|
||||
(row - self.sel_y1)) + bot_p
|
||||
dest_rgn[self.sel_x1:self.sel_x2, row] = top_p
|
||||
dest_rgn[self.sel_x1:self.sel_x2, (self.sel_y2 - 1)
|
||||
- (row - self.sel_y1)] = bot_p
|
||||
progress = progress + self.sel_w * 2
|
||||
gimp.progress_update(float(progress) / max_progress)
|
||||
drawable.flush()
|
||||
drawable.merge_shadow(TRUE)
|
||||
drawable.update(self.sel_x1,self.sel_y1,self.sel_w,self.sel_h)
|
||||
|
||||
def calc_undistorted_coords(self, wx, wy, whirl, pinch, radius):
|
||||
dx = (wx - self.cen_x) * self.scale_x
|
||||
dy = (wy - self.cen_y) * self.scale_y
|
||||
d = dx * dx + dy * dy
|
||||
inside = d < self.radius2
|
||||
|
||||
if inside:
|
||||
dist = math.sqrt(d / radius) / self.radius
|
||||
if (d == 0.0):
|
||||
factor = 1.0
|
||||
else:
|
||||
factor = math.pow(math.sin(math.pi / 2 * dist),
|
||||
-pinch)
|
||||
dx = dx * factor
|
||||
dy = dy * factor
|
||||
factor = 1 - dist
|
||||
ang = whirl * factor * factor
|
||||
sina = math.sin(ang)
|
||||
cosa = math.cos(ang)
|
||||
x = (cosa * dx - sina * dy) / self.scale_x + self.cen_x
|
||||
y = (sina * dx + cosa * dy) / self.scale_y + self.cen_y
|
||||
else:
|
||||
x = wx
|
||||
y = wy
|
||||
return inside, float(x), float(y)
|
||||
|
||||
def bilinear(x, y, values):
|
||||
x = x % 1.0
|
||||
y = y % 1.0
|
||||
m0 = values[0] + x * (values[1] - values[0])
|
||||
m1 = values[2] + x * (values[3] - values[2])
|
||||
return chr(m0 + y * (m1 - m0))
|
||||
|
||||
|
||||
register(
|
||||
"python_fu_whirl_pinch",
|
||||
"Distorts an image by whirling and pinching",
|
||||
"Distorts an image by whirling and pinching",
|
||||
"James Henstridge (translated from C plugin)",
|
||||
"James Henstridge",
|
||||
"1997-1999",
|
||||
"<Image>/Python-Fu/Distorts/Whirl and Pinch",
|
||||
"RGB*, GRAY*",
|
||||
[
|
||||
(PF_SLIDER, "whirl", "Whirl angle", 90, (-360, 360, 1)),
|
||||
(PF_FLOAT, "pinch", "Pinch amount", 0),
|
||||
(PF_FLOAT, "radius", "radius", 1)
|
||||
],
|
||||
[],
|
||||
python_whirl_pinch)
|
||||
|
||||
main()
|
||||
|
68
plug-ins/pygimp/py-compile
Executable file
68
plug-ins/pygimp/py-compile
Executable file
@ -0,0 +1,68 @@
|
||||
#!/bin/sh
|
||||
# called as "py-compile [--basedir DIR] PY_FILES ...
|
||||
|
||||
if [ -z "$PYTHON" ]; then
|
||||
PYTHON=python
|
||||
fi
|
||||
|
||||
basedir=
|
||||
|
||||
case "$1" in
|
||||
--basedir)
|
||||
basedir=$2
|
||||
shift 2
|
||||
;;
|
||||
--help)
|
||||
echo "Usage: py-compile [--basedir DIR] PY_FILES ..."
|
||||
echo "Byte compile some python scripts. This should be performed"
|
||||
echo "after they have been moved to the final installation location"
|
||||
exit 0
|
||||
;;
|
||||
--version)
|
||||
echo "py-compile version 0.0"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# = 0 ]; then
|
||||
echo "No files given to $0" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# if basedir was given, then it should be prepended to filenames before
|
||||
# byte compilation.
|
||||
if [ -z "$basedir" ]; then
|
||||
trans="path = file"
|
||||
else
|
||||
trans="path = os.path.join('$basedir', file)"
|
||||
fi
|
||||
|
||||
$PYTHON -c "
|
||||
import sys, os, string, py_compile
|
||||
|
||||
files = '''$*'''
|
||||
print 'Byte-compiling python modules...'
|
||||
for file in string.split(files):
|
||||
$trans
|
||||
if not os.path.exists(path) or not (len(path) >= 3 and path[-3:] == '.py'):
|
||||
continue
|
||||
print file,
|
||||
sys.stdout.flush()
|
||||
py_compile.compile(path)
|
||||
print" || exit $?
|
||||
|
||||
# this will fail for python < 1.5, but that doesn't matter ...
|
||||
$PYTHON -O -c "
|
||||
import sys, os, string, py_compile
|
||||
|
||||
files = '''$*'''
|
||||
print 'Byte-compiling python modules (optimised versions) ...'
|
||||
for file in string.split(files):
|
||||
$trans
|
||||
if not os.path.exists(path) or not (len(path) >= 3 and path[-3:] == '.py'):
|
||||
continue
|
||||
print file,
|
||||
sys.stdout.flush()
|
||||
py_compile.compile(path)
|
||||
print" 2>/dev/null || :
|
||||
|
50
plug-ins/pygimp/pygimp.spec
Normal file
50
plug-ins/pygimp/pygimp.spec
Normal file
@ -0,0 +1,50 @@
|
||||
%define ver 0.3
|
||||
%define prefix /usr
|
||||
|
||||
%define py_ver 1.5
|
||||
%define gimp_ver 1.0
|
||||
|
||||
Name: pygimp
|
||||
Version: %ver
|
||||
Release: 1
|
||||
Summary: A python extension allowing you to write Gimp plugins in Python
|
||||
Copyright: GPL
|
||||
Group: X11/Applications/Graphics
|
||||
Packager: James Henstridge <james@daa.com.au>
|
||||
Requires: gimp python
|
||||
|
||||
Source: ftp://ftp.daa.com.au/pub/james/pygimp/pygimp-%{ver}.tar.gz
|
||||
BuildRoot: /tmp/pygimp-root
|
||||
|
||||
%description
|
||||
pygimp allows you to write Gimp plugins with the python language. Unlike
|
||||
script-fu scripts which only have access to functions in the PDB (procedural
|
||||
database), pygimp plugins have access to all functionality that C plugins
|
||||
have, including direct pixel manipulation that is required for many plugins.
|
||||
|
||||
%prep
|
||||
%setup
|
||||
CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{prefix}
|
||||
|
||||
%build
|
||||
make
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
make DESTDIR=$RPM_BUILD_ROOT install
|
||||
|
||||
%files
|
||||
%{prefix}/lib/python%{py_ver}/site-packages/gimpmodule.so
|
||||
%{prefix}/lib/python%{py_ver}/site-packages/gimpenums.py*
|
||||
%{prefix}/lib/python%{py_ver}/site-packages/plugin.py*
|
||||
%{prefix}/lib/python%{py_ver}/site-packages/gimpshelf.py*
|
||||
%{prefix}/lib/python%{py_ver}/site-packages/getvals.py*
|
||||
|
||||
%{prefix}/lib/gimp/%{gimp_ver}/plug-ins/clothify.py
|
||||
%{prefix}/lib/gimp/%{gimp_ver}/plug-ins/tkcons.py
|
||||
%{prefix}/lib/gimp/%{gimp_ver}/plug-ins/gimpcons.py
|
||||
%{prefix}/lib/gimp/%{gimp_ver}/plug-ins/pdbbrowse.py
|
||||
%{prefix}/lib/gimp/%{gimp_ver}/plug-ins/sphere.py
|
||||
%{prefix}/lib/gimp/%{gimp_ver}/plug-ins/whirlpinch.py
|
||||
|
||||
%doc README NEWS COPYING doc/*.html
|
Reference in New Issue
Block a user