Showing posts with label development. Show all posts
Showing posts with label development. Show all posts

Wednesday, May 15, 2013

GIMP GSoC 2011 - Seamless Cloning Project - Technical Overview & Status

Recently, I was asked by email to help with the status of my GSoC (2011!) project. So before I say anything about that, let me explain a few things about my current situation.

For those of you who didn't figure it out already from the lack of activity on this website (and the lack of my activity on the web in general), due to my current real-life situation, I barely have any free time except for those few precious hours in the weekend in which I try to run my own life.

This means that my open-source activity went to a level which is not enough to do anything which requires long sessions (*cough* coding new stuff *cough*), and only translations of open source software are being kept in progress (very slowly, but they are being worked on and I'll commit them when I have enough material).

Now that I said that, and now that you know why I'm rather unresponsive by email/comments to this site, let us begin a technical overview of the project status. Note that this was originally written as an email, so I'll sometimes write as if I'm addressing someone specific in a conversation, and sometimes I talk in general (3rd person). Please ignore this inconsistency...

Technical Overview & Status

Proposal
Unfortunately, I failed to find the original proposal. However, you can find the proposal which I recorded in the GIMP wiki. The proposal is located here.

Papers
I'm listing them here, it will become clearer once you see the modules listing.

Modules
The project is divided into 3 main modules
  • A library for creating fine triangular meshes - poly2tri-c
    • The first part of this library is a C port of a library for creating Constrained Delaunay Triangulations, which are basically "nice" triangulations of existing outlines with/without holes.
      The original library is poly2tri, and the C port I wrote can be found in poly2tri-c's repository under the poly2tri-c/p2t folder
    • The second part of this library is an implementation of the Delaunay Terminator algorithm for what we call a Delaunay Refinement.
      • Delaunay Triangulations are triangulations which are considered "nice", meaning that most triangles are more or less of equal size, without too big or too small angles.
      • Delaunay refinement is the process of taking a Constrained Delaunay Triangulation (which is not exactly Delaunay due to constraints such as outline that must be respected) and refining it by inserting more and more points. The process terminates when the resulting triangulation is almost Delaunay.
      • The implementation of the algorithm above was made from scratch and in fact was the biggest part of the GSoC project (the assumption was that there was an existing open source library to do this. Apparently it wasn't so...)
      • My implementation can be found in poly2tri-c's repository under the poly2tri-c/refine folder
    • The third and final part of this library is an implementation of a triangular mesh render. The render basically takes a mesh created from the refinement process, a buffer to fill and a vertex-to-color function, and creates an image of the mesh in the specified resolution and size.
      • This is another implementation from zero, although quite trivial and could probably be made more efficient
      • The original article used OpenGL to do this rendering, resulting an ultra-fast renderer. Since the project was done when GIMP/GEGL were in an unclear state regarding usage of graphics hardware acceleration, it was done on the CPU purely which is much slower (yet still almost interactive - less than a second for rendering regular objects)
      • My implementation can be found in poly2tri-c's repository under the poly2tri-c/render folder

  • The second part of the project is a GEGL operation for doing the actual seamless-cloning operation.
    • In brief, here is a description of the process (needed to understand the state of the code):
      • Do a heavy preprocessing step for creating a fine triangular mesh from the outline of the pasted area
      • Now, for each render attempt, compute the color differences between the edges of the paste and the background image, and use the previously created mesh to interpolate the differences in the colors along the entire area of the pasted image. Add the interpolated color differences on-top of the paste and you get a seamless pasting!
    • The GEGL implementation of the operation can be found under gegl/operations/common/seamless-clone (in the soc-2011-seamless-clone branch):
      • Files beginning with sc-* are part of a "shared library" with the code required to do seamless cloning
        • This library is used using the GeglScContext object (sc-context.h) which manages a seamless cloning operation for a specified buffer to use as a paste.
        • GeglScContext implements smart logic to notice when a paste doesn't change between rendering sessions (i.e. calls to the process function) in order to avoid re-doing the heavy preprocessing step
        • Ideally, GIMP would use this "seamless cloning library" to implement seamless cloning with an internal op that does not need to do this check over and over, since the paste can't change when moving it on the canvas in the GIMP UI. However, currently gimp uses the GEGL op which is described below in a rather dumb way...
        • This library even exposes a pkg-config file to be easily linked against later...
      • seamless-clone.c implements gegl:seamless-clone - A simple seamless cloning operation using the above library.
      • seamless-clone-compose.c implements gegl:seamless-clone-compose - A simple meta-op for GEGL that composes the seamless paste above a given background...
    • Finally, in order to have the triangulation algorithm included, a copy of poly2tri-c is included under the libs directory of GEGL. This is since poly2tri-c has no package that can be installed and it was asked for so that developers won't need to download additional source code from more locations. This is not a desired situation, yet I'm unaware of any package owners for various Linux distributions which would be willing to help with distributing poly2tri-c as it's own package. If any such developer would be found, send them to me and I'll give them any access/help to the repositories (and I'll do any code modifications needed)

  • A GIMP tool using the seamless cloning GEGL op
    • The tool is a bit buggy in terms of refreshing the canvas (sometimes, artifacts are left when dragging the paste)
    • Additionally, it is inefficient since it doesn't use the library directly and so it does the check of whether the paste buffer changes each time
    • I'm not sure whether the errors regarding non-continuous pastes (with holes and/or composed of several unconnected parts) do find themselves into the GIMP UI in a proper way...

GIMP/GEGL TODO
  • Make GIMP check for the presence of the seamless cloning operation on the startup of the tool
  • Make GIMP use the library directly (and check for it's presence on compilation time)
  • Conditional OpenGL for doing the rendering of the triangular mesh!
    • Implementing the OpenGL rendering in poly2tri-c should be very easy for anyone knowing OpenGL. I'll do it if GIMP/GEGL accepts OpenGL (not OpenCL! That's different!) into the pipeline
  • Fix the described bugs in the GIMP tool UI

Poly2tri-C TODO
  • Code cleanup, prepare for distribution (I'll do that - it requires less coding then the GIMP stuff and does not require a long coding session - so I can do it on my short available time periods)

Sunday, October 23, 2011

Quick Update - NGtk

To those of you who have read my previous blog post regarding NGtk, here is a quick status update:
  • NGtk works. Tested the XLib and NCurses backends on several linux distributions, and tested the WinApi backend on many versions of windows. I have a calculator app working with keyboard and mouse support.
  • Keyboard focus is crappy, in all backends. Currently, I just tell all the widgets to listen to keyboard events. This is not something that is hard to fix - an hour or two.
  • In backends with custom drawings (XLib, NCurses), the widget state isn't considered when drawing (so the widget looks the same all the time (if it's visible)). Not a bug, but could use some fixing. Base code for fixing that is already there.
  • Clicking on disabled Widgets in the WinApi backend causes the mouse event to pass to the parent container (instead of being sent to /dev/null). Does anyone actually care about this? Can this do any harm? Anyway, the nice guys at Stackoverflow suggested a solution that should be easy to implement (but it's not top priority at the moment).
  • Removing widgets from their container isn't tested well enough. That's not a bug, but I simply can't gaurantee good behaviour
Also, here are some good things:
  • It works!
  • It doesn't crash
  • It doesn't leak memory (take that Gtk+!)
  • Valgrind is generally happy
  • Did I mention that it works? :P
I handed in NGtk to my proffessor, which means I'm now on my own with this project. Expect release 1.0 soon (my submission was titled 0.99). For those who want to take a look at the API usage already, you can take a look at the tester program: main.c (forgive me for the ugly macro in line 204, there is already a way around it in the code on my computer).

It is useable already (you can get the link to the project homepage from the main.c link), but I deeply recommend waiting for me to solve the above technical issues.

By the way, I did 40 km of bicycling in the city last friday (October 14th) in the Sovev Tel-Aviv event. It's the first time I participate, and I really enjoyed. Riding the bicycle on the busiest highways in the country and then along the sea shore together with other hundreds of people, is a great experience. So, if you can participate next year, I highly recommend that you do so ;)

Monday, August 29, 2011

[GSoC-2011] Final Results and How to Try

I am very glad to announce that I now officially passed the Google-Summer-of-Code 2011 :) The email from Google arrived in the last few days, and the official Google announcements on the GSoC results (of all projects) are supposed to be published tomorrow.

S/He is eyeing you :)
Sources: background, paste
Now, it’s time to publish the instructions on how to get and try it for the people who want to test it. There are some known bugs, and probably some unknown bugs, so be warned.

Compilation and Set-Up Instructions
  1. You should know how to build of GIMP and GEGL from Git. A partially outdated guide is available here, and some things are explained in more depth here.
  2. Instead of building the GEGL master (main) branch, switch to the soc-2011-seamless-clone branch. You can do this by running git checkout soc-2011-seamless-clone. Compile it with the regular flags – nothing special is needed.
  3. After building the updated version of GEGL, it’s time to build the updated version of GIMP. Switch to the soc-2011-seamless-clone2 branch, and build it.
  4. Before running GIMP, you must set the environment variable p2t_refine_steps to some number defining the maximal amount of points to be used in the mesh (in plain English, more should theoretically produce better result). I know this is annoying, I will get rid of it as soon as I finish debugging a certain code part. The typical number I use is 500 for pastes of around 200x200 pixels, and you should probably increase it if you wish to work on large pastes. If you are using the bash terminal, do export p2t_refine_steps=500 (and change the number as you wish)
  5. Run GIMP.
Usage Instructions

Basically, you can just try copying a part, selecting the Seamless Clone tool (Shift+L) and clicking anywhere on the image to start the tool’s interaction. Click Enter to apply the final result. If this doesn’t work (and/or crash), then the instructions below are for you.
  1. Run Gimp :)
  2. Open the image that you wish to use as the background, and open the image you wish to paste into the background. Copy the part you want to paste. Note that opacity of that part will be treated as if it was binary – parts under 50% opacity will be removed, parts of more than 50% opacity will be completely opaque. The shape can be any shape, as long as it follows the following rules:
    1. It must not have holes (Temporary limitation)
    2. It must be continuous, i.e. composed of only one part (Temporary(?) limitation)
    3. It must not have any long thin areas (Temporary(!) limitation).
      This means that if you have any area which is 1 pixel wide and is 3 pixels long or more (i.e. a thin spike), it will crash. Solution for this was already devised, I just need to code it. Select the Seamless-Clone Tool (Either by clicking the second tool on the toolbox that has the same icon as the move tool, or by doing Shift+L).
  3. Click anywhere on the canvas while the background layer is active. The paste will be centered on the cursor, and so the cursor should be in a place where the entire paste is inside the background boundaries (both inside the rectangle defining the layer, and inside an area where all the background below it is opaque). This limitation will be enforced by the User Interface later.
  4. Move the paste by clicking on it, dragging and releasing. If you move it slow enough (which actually shouldn’t be so slow), you’ll see the preview updating while you are moving.
  5. Click Enter to Apply the effect.
Known Bugs
  • All the above mentioned crashes and bugs :)
  • Due to not yet complete memory management, the tool leaks memory from it’s preprocessing.
  • Converting to tile-based processing is NOT 100% done, so it may crash on large pastes. Don’t ask me how large since I didn’t try anything more than 300x300 on my machine.
Other TODO’s
  • Integrate the tool with the help system
  • Test better the interaction when the the active image/display/drawable are switched during the interaction of the tool.
  • Get a decent tool icon. Anyone with ideas for the visual metaphor to be used by a seamless paste tool, is more than welcome to leave them here as comments! I do design icons, but I don’t have an idea for this one.

Monday, August 15, 2011

GSoC 2011 - (Almost) Final results and thanks!

The end of Google Summer of Code 2011 is near, and I have failed to post enough updates on my blog. But that does not mean one bit that I failed to make progress. I'm proud to present you with my results:

Result, using my GIMP tool :D
The image to paste (source)
The image to paste into (source)
Licensed under Creative Commons Attribution-Share Alike 3.0 Unported

My tool allows you to move the paste on the image and see it update according to it's environment, so that it will paste seamlessly. It's not real-time yet, since I recompute some values that should be cached everytime, but most work to enable caching is done, and I hope to reach that before the final deadline. (Even if it won't be before the deadline, I will do it even after GSoC ends).

This is also the time to thanks all the people who made this possible:
  • The authors of the Coordinates for Seamless Cloning article, who developed this algorithm.
  • Prof. Daniel Cohen-Or, the professor who taught me computer graphics at the university, and helped me understanding the article (he is also one of the article authors).
  • My GSoC mentor, Michael Natterer (aka mitch), who agreed to mentor me and assisted me when I was stuck.
  • Mason Green, the original author of the poly2tri library, which was heavily used in the project for computing interpolation meshes. I would have never reached the project deadline without his amazing library.
  • Prof. Jonathan Richard Shewchuk, who developed some of the geometrical algorithms that were used in this project.
  • Finally, special thanks to all the great guys on the GIMP and GEGL irc who helped a lot - mitch, Bat`O, pippin, Alexia_Death, Mikachu, and more.

Sunday, August 7, 2011

Open Devhelp books installed in unusual locations

If you are a GNOME developer, there are high chances you encountered this problem - you install your beta versions to a seperate prefix (something like /opt/my-beta instead of the regular /usr), and then when you come to browse their documentation in Devhelp, it fails to find them. Some will be tempted to sudo, and then symlink the documentation to /usr/share/gtk-doc. Personally, I'm not a fan of sudo-ing and messing around...

Today I had enough of this, and decided I'm going to solve this. A quick search in the Devhelp source code found the code that searches for books. The book_manager_add_books_in_data_dir () function searches SOME_PREFIX/gtk-doc/html for Devhelp books, and it's called from dh_book_manager_populate () with the directories returned by g_get_user_data_dir () and by g_get_system_data_dirs ().

Thanks to some help from Mikachu (from #gimp irc), which matched the much longer description on the freedesktop basedir-specs, I found out that appending a directory to the environment variable $XDG_DATA_DIRS is enough to make Devhelp search for documentation there.

Sweet! That was much easier than I thought it would be :D

So to summarize, this is what you do:
  1. Compile your program, while setting the installation prefix to some prefix $PREFIX
  2. Build and install it (make and make install)
  3. Find your installed gtk-doc documentation. Usually it is located on $PREFIX/share/gtk-doc/html/YOUR_PROGRAM. Make sure that directory contains a file with the suffix of .devhelp.
  4. Set the $XDG_DATA_DIRS environment variables, and prepend (don't append!) that directory (usually $PREFIX/share) to that variable. In bash syntax, you should type
    export XDG_DATA_DIRS=$PREFIX/share/:$XDG_DATA_DIRS
Why prepend and not append? Well, apparently Devhelp doesn't seem to like having two books with the same title, so it takes the first one it finds... Since it follows the directories in that environment variables by their order, it means that we should add our directory to the begining of the search path.

Note that this method has 2 cons:
  1. You can't view previous versions of the documentation, since as I said Devhelp takes only the first version it finds
  2. You must launch Devhelp with the above environment variable set. So either lunch it from your build console, or create a script to modify the variable and then lunch Devhelp. Note that IDEs that launch Devhelp (like anjuta, and gedit with plugins) must have the variable set for themselves (by launching them with the variable set already).
So, it's not perfect. But way better that symlinking stuff into the /usr/share/gtk-doc directory. This also shows why open source is so good - "If you don't like it, fix it!". Or as I prefer to say "If you don't like it, hack it" :D

Monday, February 28, 2011

GIMP Developer Meeting

Today (February 28th, 2011), at 10pm CET a meeting of GIMP developers is scheduled on the GIMP developer IRC.

Agenda:
  • GSoC 2011 - ORG Application deadline is in 11 days!
  • Bug fixing priorities
  • Future development?
  • Make an official wiki working again (i.e. make wiki.gimp.org pointing at it)! Can be done either by making http://gimp-wiki.who.ee/ the official wiki, or potentially using some other available servers (will be discussed in depth on the meeting)
  • Make a roadmap on the official wiki
  • Try and decide on clear release policy for beta builds - I personally would like to see more recent beta releases, and the last one was 7 months ago!
  • Anything else? =)
If you want to discuss GIMP's future, GSoC this year, and just listen, please come. We will meet on irc://irc.gimp.org/#gimp (Users without IRC client can connect using this link).

Edit: The wrong time was displayed - it's february 28th, not the 27th

Saturday, November 6, 2010

New GEGL operation!

Hello,

As I mentioned, I started working on some gegl operations, and I'm glad to announnce my first official gegl operation - whirl and pinch! This operation is a port of the known gimp plugin to gegl (since eventually every gimp plugin will have to be ported).

How to install it (linux users):
  1. Copy the file operations/workshop/whirl-pinch.c (from inside gegl's source tree) into ~/.local/gegl-0.1/plug-ins/
  2. Make sure your enviroment contains gegl's build dependancies
  3. Type 'make' inside ~/.local/gegl-0.1/plug-ins/

Now, you will be able to access the operation inside gimp (using the "GEGL Operation" tool) and get a live on-canvas preview of it!

Whirl and pinch gegl op!
"Whirl and Pinch" live on canvas!
BTW - last night I closed 6 gimp bugs :)

Monday, August 30, 2010

Some thoughts on hunting bugs (Software in General)

I don't tend to complain too much, but it was annoying as hell to track down this bug, so I though I'll share some of the joy with you =) This post is mainly for software users (not GIMP-specific) as it should give you an insight on how to track the exact cause of a bug, and so make better reports and make it easier for the developers to fix the bug =)

Developers may also enjoy this post - thinking about this bug and how I tracked it, it is in fact a very funny bug :D

Tuesday, July 27, 2010

Help Us Help You! A short guide on reporting (GIMP) bugs

Hello,

After a recent increase in the amount of bugs which are reported on the GIMP bugzilla, I thought it might be a good idea to give some helpful tips about reporting bugs in GIMP (and in general in most open-source programs) - these will help us the developers to help you:
  • In case of broken functionality, please try to:
    • See if you can reproduce the problem. If you can't reproduce it maybe it's not a bug.
      Try different scenarios to reproduce the bug (i.e. try reproducing it with different images or with similar settings of the tools/plugins/etc.)
    • List the exact steps which are needed to reproduce the bug. If we don't have the steps, we won't be able to see the bug ourselves.
    • Tell us the exact version of GIMP (you can find it in the Help->About menu)
  • In cases when GIMP or one of it's plugins crashes, we'll need more technical details about your system (in addition to the details about broken functionality):
    • The name of the operating system you are using, and it's version (for example "Windows XP service pack 3"/"Ubuntu Linux 10.04")
    • For advanced users: try to provide a stack trace. To do this, launch GIMP from the command line, with the flag --stack-trace-mode=yes. Now when GIMP crashes, you'll see a question in the terminal asking you if you want to print a stack trace. Print it and attach it to your bug report.
    • For regular users: Launch GIMP from the command line (if you know how to), and if any error is shown when GIMP crashes, attach it to your bug report.
  • Enhancement requests are not bugs.
    If you have an enhancement request you can post it on any of the following places:
  • Enhancement requests can be filed as bugs, but only after they were approved as a feature that should be included in GIMP. To get feedback on your enhancement request, use the developer mailing list or the developer IRC.

Finally and most important of all: Check if the bug was already reported. Unless you are using a development release, it's very likely that the bug you encountered was already reported by someone else.
You can search for existing bug reports using the search form on the bugzilla page of GIMP. Try entering some key word related to your bug and see if it was already reported.

For more information about submitting bug reports to GIMP, see the GIMP bugs page.

For your convenience, here is a list of commonly reported bugs of the last month:
  • Bug 623563 - Text tool crashes Gimp
  • Bug 622608 - GIMP crashes when clicking any scroll bar from combo boxes
  • Bug 606247 - Crash using rectangular select tool with fixed aspect ratio on Windows XP
  • Bug 624089 - Copy-paste doesn't work (GIMP 2.6.10 - Resolved and fixed)

Thanks for reporting bugs and thanks for taking the time to read this post - it will help us help you! =)

Edit 13:27 IDT (GMT+2) 27.07.2010:
To make it clearer (as it was pointed out by peter sikking): The GIMP UI brainstorm blog is only for enhancement requests for the UI - i.e. ways to make the user interface better. It's not for general enhancement requests.

Monday, July 12, 2010

Progress - Multicolored text layers in GIMP

Hello again,

Before I vanish to study to some more unexpected tests here is a small update on multi-colored text layers. mitch (Michael Natterer) has fixed up a patch, which now allows the text core to render multicolored text! Until now, text in GIMP was rendered as an alpha mask for a color layer which prevented my patch from being any good. The original reason for this, was to avoid having to handle images with different color modes (indexed/whatever) by rendering only the shape as a mask.

So, I tried my patch again today. It works, if you want gray text :D I have some issues with the conversions, but the patch basically works.
I did say it basically works - even if it's not the color you expected :D
For those of your who want to try this out, here is the bug report Bug 620674 - Adding support for multi-colored text layer. There are two patches attached - one patch by me which adds the functionality in the gui/core for specifying several colors in one layer, and the other patch (by mitch) which enables rendering of the text-layout itself instead of using it as a mask on a color layer.
Download both patches to the directory with the source of GIMP, and run the following commands in bash:
cd GIMP_SOURCE_DIRECTORY # replace with the actual path
patch -p1 < MITCH_PATCH # replace with the actual path to the patch file
patch -p1 < MY_PATCH # replace with the actual path to the patch file
Now re-compile GIMP and enjoy =)
The color selection yields the wrong colors (bright shades of gray) but it works.

I'll be back next week hopefully, but it may take a bit more time (Big exams...)

p.s.
I see that a very big fraction of the readers of this blog are from Russia - so спасибо! (For English speakers, that's thanks in Russian)

Sunday, July 11, 2010

Multithreading in GIMP, Learning to write GEGL operations

As some of you have seen, GIMP is being ported to a new graph-based image core, called GEGL. Those of you who have experimented with GIMP 2.6.X and later, have possibly found the GEGL tool (Under the tools menu) which allows you to see on-canvas preview of some operations such as blur, perlin noise (which some of you know as clouds), and more.

Thanks to the very generous help of Øyvind Kolås (aka pippin), I have started to write a GEGL operation for GIMP. Too practice I decided to write a Pixelize operation (not too complex, but also works on a neighborhood of pixels and not on a single pixel).
This is the first time which I implement an image processing algorithm which is not based on samplings for distortion (like the waves filter), and although I know the theory for a lot of time, it still has some bugs with wrong indexes :P

When I finish this, I'm going to post it here along with a log of my chat with pippin on the IRC (on irc://irc.gimp.org/#gegl) to clear out some of the common questions about GEGL. Hopefully I'll be able to post a mini-guide (or more correctly, what I have learned, since I still have a lot to learn to write a full GEGL guide) to introduce other people to writing GEGL operations.

The discussion originally started because I was disappointed that libgimp (the library for interactions between plugins and GIMP) is not thread-safe, meaning that you can't have two threads modifying the same drawable concurrently (unless of course you want to "Create Modern Random Art" as someone called it). And it's impossible not practical to fix it (due to the amount of time it would take).

Apparently, GEGL is multi-threaded (more on this later, in my next post) and it usually works (but sometimes the threads reach a dead-lock, a situation in which both threads are blocking one another from progress since they are waiting for shared resources/memory). It still requires a bit of fixing (Cheer up for pippin! He needs some more motivation to fix this! ;-) )

So, for those of you who want to try "bleeding edge" and unstable GEGL, set the environment variable GEGL_THREADS to 2 (or whatever amount of threads you want GEGL to use) and expect up to 200% speedup (in ideal world. Practically some parts of the code which are executed sequentially, added to the limitation of the memory access speed, both will cause it to run slower depending on the operation and your system) with GEGL (or 0% if you reach a deadlock).
Be warned: this is supposed to be buggy. Please do not report bugs with this, unless you strictly know what you are doing.

Edit: Made the post more correct about the possible speedup. 200% speedup is a naive optimistic view, which is ain't true (and I forgot to mention this)

Sunday, June 20, 2010

Gimp Updates: Multi-Colored Text, PDF Export, Hebrew Translation and more...

Here are some quick updates from the last several days:
  • First announcement: GIMP is currently being translated to Hebrew!
    As a Hebrew speaker, I was very disappointed from the state of the Hebrew translation of GIMP. So, I decided to start and translate it, and I already fixed several bugs to make the translation to Hebrew easier.
    The translation is going on well, and I'll start updating the main git repository with the translations soon.
  • I have some progress on the PDF export from GIMP. Hopefully it will be committed this week - all the blocking issues were resolved and basically all I need to do is to connect the GUI.
  • I did try to implement multicolored text support in GIMP (several colors in the same layer) and it failed for the most annoying reason - text in gimp was rendered as an alpha mask for a color layer.
    Mitch fixed it recently, so this means that I'll be able to retry my patch somewhere soon.
And finally, I have to say that I'm quitting (at least for now) the attempt to save single window mode layout in GIMP. It's not so practical right now, since the object which hold the data (GimpDockWindow in swm and GimpColumn in mwm) are being destroyed when switching between modes.
After discussing it with Martin, I understood fixing this is not trivial, so I'm not going to do it anywhere soon...

Friday, June 18, 2010

Updates and Flies

First of all, before I forget, many thanks to Alexandre Prokoudine who added this blog to GraphicsPlanet. Go check this site - it lists blogs of many open source projects and their developers.

There is more progess on the single window mode - saving it partially works now (or more correctly, loading it works). The post about the single window mode is updated as I make progress in that direction.

The blog is now printer friendly, at least for firefox users - please notify me if you see anything which doesn't look well in printing.

And finally, this blog is also about art and photography. Here is a picture I took today, which I like (click to go to the page with the fullsize view)

2fly by ~LightningIsMyName on deviantART

Wednesday, June 16, 2010

Progress - Saving Single Window Mode settings in GIMP

Two days ago, I promised to try and work on the single window mode in GIMP. Well, I have worked on it, and I know basically know what needs to be done.

Note: This post is mainly for people interested in the GIMP's source. For others, just take my word that there is some progress =)

So, how is single window mode implemented in GIMP?
The heirarchy is the following:

The heirarchy of the user interface containers inside GIMP
GimpDockable's inside GimpDockbook's inside GimpDock's

GimpDock - which is very similar to a GtkVBox
  |-- GimpDockbook - this is a small area which allows tabbing of several GimpDockable's
     |--GimpDockable - This holds the actual content and user interface elements

Single window mode, introduced two new containers - left and right. In each of these 2 new containers, we can store several GimpDock's in a row (see the image from my previous post, to see how this looks).

Here is a typical part of the sessionrc file, a file in GIMP which holds your session preferences:
(session-info "toplevel"
    (factory-entry "gimp-dock-window")
    (position 0 25)
    (size 200 523)
    (open-on-exit)
    (aux-info
        (show-image-menu "false")
        (follow-active-image "true"))
    (gimp-dock
        (book
            (current-page 0)
            (dockable "gimp-layer-list"
                (tab-style icon)
                (preview-size 32))
            (dockable "gimp-channel-list"
                (tab-style icon)
                (preview-size 32)))
        (book
            (position 236)
            (current-page 0)
            (dockable "gimp-color-editor"
                (tab-style preview)
                (aux-info
                    (current-page "GimpColorSelect")))
            (dockable "gimp-brush-grid"
                (tab-style preview))
            (dockable "gimp-pattern-grid"
                (tab-style preview)))))
So, here is a short analysis of what's going on:
(session-info "toplevel"...) - means we are talking about a top-level window
(factory-entry "gimp-dock-window") - means we are talking on a dock window (other windows are also saved, for example the location of the save dialog)
(current-page 0) - means that the current open tab is the first one
The rest is pretty self explanatory...

So, how am I supposed to implement saving a single window mode?
"Simply", add two parameters directly after (factory-entry "gimp-dock-window"). This entries are single-window-mode-position which can be one of "left", "right" and "floating" (since you can still have floating docks in single window mode). And, for docks which have one of either "left" or "right" value, I'll have to add a "dock-index" property which indicates their index in that side (left/right).

Here is the bad part - I'll need to add these configuration properties to the docks themselves, and to the configuration file. Then, I'll also have to support parsing these parameters when activating single window mode. This is going to be long, and annoying but it also has a bright side - I know how to do this =)

And with this somehow optimistic summary of what needs to be done - I'll go to sleep (I should really find times to update this blog during the day instead of writing at midnight :P).

Edited - Jun 16, 3:59 AM:
1. fixed a wrong class name inside the image of the gui
2. Got thumbs up about this way of implementation from martin (aka enselic) - the guru behind the single window mode.

Edited - Jun 18, 12:22 PM:
Loading the settings of single window mode works! BUT, saving them doesn't :-( The problem is that if we are currently in single window mode, dock windows are not saved at all (even the fact that they exist is not saved).
I believe they (the dock windows) are being destroyed during the switch to single window mode, after the dockables inside them were attached to the "uber" image window (that's how it's called in the code, I haven't chosen uber myself).
If I'm true, this will also explain why when I quit after switching to single window mode, the settings that were loaded for single window mode, are lost (since they were associated with the dock windows and these were destroyed).
There is no easy way out of this - I am starting to understand why mitch said this problem is so evil...

Sunday, June 13, 2010

Single window mode - wonderful for the user, horrible for the developer

Some of you may have seen the single window mode introduced in 2.7. It's wonderful to use (no need to suffer anymore from the huge amount of floating docks!). You can dock all the dialogs on the sides and customize the location and size of every one of them. All, inside the main window!

New features in this screenshot are layer groups, resource tagging, on-canvas text editing and on canvas dialogs, single window mode and paint-dynamics dialog (you can configure each dynamics settings in more way than you can imagine :D)
But, here is the catch - you can't save this layout! Every time you start Gimp, you will have to go to Windows->Single-Window Mode to enable this, and the location of the docks won't be saved. In other words, you have to rearrange the window layout every time, when using single window mode.
And to make it worse, when trying to fix this mitch warned me:
you actually picked the most evil current problem ;-)
Having to set your layout again every time IS VERY ANNOYING.  I'll try to fix this, but after looking at it I'm sure it's not going to be easy. Oh well, someone has to do this =) Starting this at the middle of the night (an hour ago) wasn't so smart - I'll go to sleep and do this (or at least try to) sometime during this week...