Minimum user base according to our last poll (rounded, and I am sure that many users do not participate in polls):
FLTK 1.0.x: 40 FLTK 1.1.x: 400 FLTK 1.3.x: 200 FLTK 2.x.x: 360 possible user base if everyone agrees to move to FLTK 3.0: >1000 End of confusion why 1.3 is active and 2.0 is dead? Priceless (tm). Hi, those of you who read the commit logs will have been blasted with huge commits in the FLTK 3.0 branch. Yes, I am actively developing this again, and guess what, so far I believe I am pretty successful. This is how it works (plus some trickery): the FLTK3 header reside in ./fltk3, FLTK2 headers remain in ./fltk, and the FLTK1 headers are as always in ./FL. The source code also stays in ./src, and even the individual source file names remained the same. Using the current FLTK1 makefiles and IDEs should be no problem! All code in ./src is currently renamed into FLTK2 style naming (namespace is fltk3 though) which is a lot more logical than the FLTK1 naming ever was. Other than that, FLTK3 is internally a find/replace version of FLTK1 plus a hand full of minor features. When done, the FLTK3 source code should be as stable as the FLTK1 core, and as readable. Almost no extras were introduced to allow FLTK1 and FLTK2 wrapping. So how does the wrapping work? All FLTK1 and FLTK2 emulation is done in header file only! There is no extra code to link! Just make sure that the correct headers are found and you are good to go. Emulation works like this: the FLTK3 base class has a new member called "wrapper". The wrapper points to another class that is the emulation layer. This can be FLTK1, FLTK2, or any other interface or language binding for that matter. All FLTK1 and FLTK2 classes are derive from fltk3::Wrapper and have only a single member variable _p, which points to the FLTK3 implementation of the class. The emulation layer redirects all calls to FLTK1 and 2 into new calls in FLTK3. Once the emulation layers are complete (and there is a definite end if we stop writing 1.3 and 2.x core code), we can change pretty much everything in FLTK3, while always keeping the API for FLTK1 and FLTK2. Tadaa, frozen in time! I have written wrappers for a bunch of classes, implementing some of the commonly used methods. The result is in http://svn.easysw.com/public/fltk/fltk/branches/branch-3.0 . Some of the test programs (hello, button, buttons, label) have three versions. hello1.cxx is the original FLTK1 hello program and compiles and runs without a single change in source code or makefile! hello2.cxx is the FLTK2 original and again runs without touching the source code or makefile! Well, hello.cxx is what could be called "native FLTK3". It looks like FLTK2 and feels like FLTK1. Only the future will show if we can make the users of both original libraries comfortable with FLTK3. Be brave! The code is quite simple. The overhead is small. Once the wrappers are done, I would hope to get all FLTK1 *and* FLTK2 users and developers on board! - Matthias PS: Some Details Documentation: I remove *all* documentation from FLTK1 and FLTK2 wrappers. FLTK3 keeps all doxygen comments and should still generate decent docs. A few manual changes may be required. Arguments and Return Types: if an argument is an Fl_Widget, it is translated to the corresponding fltk3::Widget before used as an argument. Similarly, the return type is translated from fltk3::Widget to Fl_Widget. Both operations are cheap! Callbacks: callbacks work just as is. The trick here is that fltk3::Widget::do_callback checks if a wrapper exists and translates the Fl_Widget/fltk3::Widget pointer accordingly. This is solved. Constructors: the emulated constructors simply create the requested widget and set up the wrapper. Two lines of code. Destructors: ah, now it gets more difficult. This has not been tested yet, but basically whichever destructor is called first (Original or Wrappe) will first unlink itself and then call the other destructor. Interfacing: FLTK1, 2, and 3 code can happily coexist in a single application! However, calling a wrapper function will always return arguments in the wrapper class (myWidget->parent() returns an fltk3::Group only if myWidget is fltk3; if myWidget is an FLTK1 wrapper, the return value will also be an FLTK1 wrapper, or NULL if the parent is actually an unwrapped fltk3 widget). This is all no big deal if you know what's going on. Internally, all three styles live happily together. Virtual Functions: this is a big cookie. The handle() function for example is a two-way street. It's called by the event handler, but it can also be called from the outside. This is untested, but a flag that I set somewhere will decide if the wrapper calls the original, or vice versa. It should solve 99% of the cases, if not all. Overhead: FLTK1 and 2 code wil have one additional indirection per call. Every widget has a sister widget which is just one pointer in size. I am sure this is bearable for most systems. Questions? Please feel free to ask. _______________________________________________ fltk-dev mailing list [email protected] http://lists.easysw.com/mailman/listinfo/fltk-dev
