Sven wrote: > If you had a look at the Ink tool you would have noticed that all > paint tools are extraordinarily simple. I agree that other tools > (those that draw to the display) are a lot more complex but all paint > tools are identical except that they register different GimpPaintCore > objects. So you don't even need to deal with tools at all (which is > admittedly one of the most complex and least cleaned up parts of the > Gimp code). > > All you need to do is to derive a new GimpPaintCore, either directly > from GimpPaintCore or (in case you want to make use of brushes) from > GimpBrushCore. This is all nicely abstracted in the app/paint folder > and you basically don't need to worry about anything outside this > directory. All you need to do is to implement a couple of methods. > Just take an existing paint core as an example to copy from. Thank you. This is already very helpful. So in the spirit of trying to figure things out for myself, let me try to figure out how to make a tool register a different GimpPaintCore object. Let's see -- nothing useful in tools/gimpinktool.c, which as you say is very simple. So let's look at the code for the parent class, tools/gimppainttool.c. Yes, here it is, line 230: paint_tool->core = g_object_new (tool->tool_info->paint_info->paint_type, NULL); A bit daunting, but obviously what I need to do is set the paint_type. So let's figure out where that is done. Grepping for paint_type in the tools directory gives nothing. Grepping in the entire code base gives about a dozen hits -- core/gimppaintinfo.c looks most promising. Okay, here it is, I think, line 145: paint_info->paint_type = paint_type; This is in the code for gimp_paint_info_new(), and paint_type is one of the arguments to the function. So the next step is to figure out where gimp_paint_info_new() is called. Grepping gives only one hit, fortunately, in paint/gimp-paint.c, line 109: paint_info = gimp_paint_info_new (gimp, paint_type, paint_options_type, blurb); This occurs in the code for the function gimp_paint_register(), which is declared static void, so it must be used in gimp-paint.c; let's find it. Okay, here it is, line 77: for (i = 0; i < G_N_ELEMENTS (register_funcs); i++) { register_funcs[i] (gimp, gimp_paint_register); } This is kind of scary looking, but fortunately the array register_funcs[] is created directly above, and I see that one of its entries is gimp_ink_register. I make a mental note that I will at some point need to add my new tool to this array, and then go on to look for gimp_ink_register(). Okay, here it is, in paint/gimpink.c: void gimp_ink_register (Gimp *gimp, GimpPaintRegisterCallback callback) { (* callback) (gimp, GIMP_TYPE_INK, GIMP_TYPE_INK_OPTIONS, _("Ink")); } So finally I see that paint_type is GIMP_TYPE_INK, which is defined in paint/gimpink.h as: paint/gimpink.h:#define GIMP_TYPE_INK (gimp_ink_get_type ()) And now I see that to create my new "spew" tool, I need to do the following things: 1) In app/paint, "cp gimpink.c gimpspew.c" and then edit gimpspew.c to s/ink/spew/g (don't take this literally). 2) Handle gimpink.h similarly. 3) in paint/gimp-paint.c, add an include for "gimpspew.h" and add gimp_spew_register to the register_funcs array. 4) in app/tools, copy gimpinktool.c and gimpinktool.h to gimpspewtool.c and gimpspewtool.h, then change "ink" to "spew" everywhere in the new files. 5) in app/tools, handle gimpinkoptions-gui.c and gimpinkoptions-gui.h the same way. 6) Add the new files to Makefile.am in the appropriate places. 7) In tools/gimp-tools.c, add "gimpspewtool.h" as an include, and add gimp_spew_tool_register to the register_funcs array. (I found this by sheer luck.) 8) (The hard part) Edit paint/gimpspew.[ch] and tools/gimpspewoptions-gui.c to give the desired new functionality. The code from gimpink.c is rather complex and will no doubt give rise to more questions. Does that look right? No, I see that I haven't created an icon yet. Fortunately I think I more or less know how to do this: 9) Create stock-tool-spew-16.png and stock-tool-spew-22.png and place them in themes/Default/images/tools. As I understand it, the appropriate line in libgimpwidgets/gimpstock.h will be autogenerated if in the themes directory I then do "make -C clean; make". How about that? > That is void as well. A paint core is easy enough to be understood > quite easily and since the code is in a single file, there is no risk > at all that such problems could arise. Well, I think I have demonstrated that I need to create or modify at least 10 files to produce a new paint tool, and I have probably missed something along the way. But I will admit that the danger of code collision does not seem all that large. > There are a couple of paint tools in the core. I don't see how we > could document this any better than by example. I've offered a helping > hand for anyone who wants to work on new paint tools but I am > certainly not going to waste the very few free time that I have by > writing tutorials. That's fine. I think I have more or less assembled one in this email, if it is correct. Once I understand more clearly what needs to be done to alter a file such as gimpink.c, I'll be happy to flesh it out. (And I hope that the first half of this email makes clear the difficulties of working from examples in code where there is a lot of indirection.) I'll respond to the other points separately; this is already very long. Best, -- Bill ______________ ______________ ______________ ______________ Sent via the KillerWebMail system at primate.ucdavis.edu