Am 16.06.2009 4:29 Uhr schrieb "Robb Main" unter <[email protected]>:
> #include <FL/Fl.H>
> #include <FL/Fl_Shared_Image.H>
> #include <FL/Fl_Single_Window.H>
> #include <FL/Fl_PNG_Image.H>
> #include <FL/Fl_Button.H>
>
> // for usleep used in main()
> #include <unistd.h>
>
> class splashWindow : public Fl_Window {
> Fl_PNG_Image *pBGImage;
> protected:
> virtual void draw() {
> Fl_Window::draw(); // Draw window widget first
> if ( pBGImage )
> pBGImage->draw(x(),y()); // draw PNG image over the above
~~~~~~~
Do not draw at x and y. Classes derived from Fl_Window always have a
coordinate system that starts at 0, 0 for the top left corner. X and y
though are set relative to the parent window. I am surprised that you image
renders at all ;-).
> }
> public:
> // Constructor
> splashWindow(int X, int Y, int W, int H, char *pszTitle, char *pszBGImage) :
> Fl_Window(X,Y,W,H) {
>
> pBGImage = new Fl_PNG_Image( pszBGImage );
> border(0);
> end();
> // flush(); // give fltk some cpu to update the screen
> // show();
~~~~~~~
Flush() is wrong here. Show() is possible, but probably not needed.
> }
> };
>
> class myWindow : public Fl_Window {
> splashWindow *pSplashWin;
> public:
> void show() {
> Fl_Window::show(); // Show main window widget first
> if (pSplashWin) {
> // Cleanup
> remove( pSplashWin ); // remove splash window
> delete( pSplashWin ); // deallocate it
> pSplashWin = 0;
> }
> } // show()
>
> // Constructor
> myWindow(int X, int Y, int W, int H) : Fl_Window(X,Y,W,H) {
> splashWindow *pTmp;
> pSplashWin = 0;
> // Create Splash Screen child window
> pTmp = new splashWindow( X, Y, W, H, "My Splash", "./splash-bg3.png" );
The line above is perfectly legal, but probably doesn't do at all what you
intended. See, Fl_Window can also be used as a child of another Fl_Window.
The effect is simply a rectangular area within the parent window (just like
Fl_Group) except that coordinates are relatibe to *this* Fl_Window, not the
parent Window as it is usually in FLTK.
Since new windgets are automatically added to the current group, your new
splashWindow actually becomes a part of myWindow, positioned at X/Y relative
to the top left of myWindow.
Instead, you could call Fl_Group::current(0L) before creating the new splash
window and begin() after creating the splash, so that the button is added to
the main window, and not the splash window.
> // Fl::flush();
> // Fl::check(); // give fltk some cpu to update the screen
> // Add a button to the main screen, so we know when it's displayed.
> Fl_Button *btn1 = new Fl_Button(40, 40, 200, 200, "MAIN WINDOW" );
> end();
> show();
> Fl::check(); // give fltk some cpu to update the screen
Check() does not update the screen. It checks for new events and handles
those. Flush() updates the screen. Wait(0) should do both. But they are not
needed here anyways.
> // Fl::flush();
> pSplashWin = pTmp;
> }
> };
>
> int main(int argc, char ** argv) {
>
> fl_register_images();
> Fl::scheme("plastic");
> Fl_Window *pWin = new myWindow(0, 0, 640, 480);
> // wait while splash is displayed
> /*
> There is a noticeable delay before the PNG image appears, because the
> picture is NOT rendered by the first itteration of the loop below.
> The picture is rendered when Fl::check() is called.
> I tried numerous different things (see constructor above), in order to
> "flush" the PNG image to the display immediately, but nothing worked.
> */
> for (int i=0; i<3; i++ ) {
> usleep( 1000000 );
> Fl::check();
Agaian, check() does not update any drawings.
> }
> // Now show the main window - this will remove the splash screen
> pWin->show();
> return Fl::run();
> }
Here is my suggestion. IMHO you are packing more things in your classes then
needed. You have little bugs, some of whih come from sometimes unexpected
behavior of FLTK, but you can't see them because the structure is too
complex.
I would completely separate the code for the splash screen and the main
screen. Having both windows know about each other adds complexity. Then, in
main(), you do this:
Sp = newSplashscreen(w, h); // this will load your PNG immediately and
display it as soon as the window is shown. I use the two-parameter variant
of the Fl_Window creator to give the window manager a chance to position the
screen, but the other call is fine too.
Sp->end(); // make sure we add no children anymore
Sp->show(argc, argv); // now we map the window onto the screen. This will
open the window and draw decorations, but no content until the refresh cycle
starts. Argc and argv are the parameters from the main() call and give FLTK
a chance to customize the color base according to user settings
Do {
Fl::wait(0);
} while (!Sp->shown());
// I hope I remember this correctly. This will wait intil your window is
actually visible and should also handle the first refresh, hence showing you
png.
// now, this is a bit complicated because FLTK should be able to refresh its
screen once in a while, but you probably want to load settings and other
stuff while the splash screen is up
For (job=0; job<1000; j++) {
Fl::flush();
doJob(job);
}
// ok, everything is loaded, now create and show the main screen, then hide
and delete the splash, then call Fl::run() and you should be all set.
Matthias
--
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk