Main Page Class Hierarchy Compound List File List Compound Members File Members Related Pages Examples

# tut4.cpp

TUTORIAL 4 - custom widgets

    /*
        ParaGUI - crossplatform widgetset

        TUTORIAL 4 - custom widgets

        Copyright (C) 2000  Alexander Pipelka

        This library is free software; you can redistribute it and/or
        modify it under the terms of the GNU Library General Public
        License as published by the Free Software Foundation; either
        version 2 of the License, or (at your option) any later version.

        This library 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
        Library General Public License for more details.

        You should have received a copy of the GNU Library General Public
        License along with this library; if not, write to the Free
        Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

        Alexander Pipelka
        pipelka@teleweb.at

        Last Update:      $Author: pipelka $
        Update Date:      $Date: 2001/01/31 17:23:17 $
        Source File:      $Source: /usr/local/CVSROOT/linux/paragui/doc/html/tut4_cpp-example.html,v $
        CVS/RCS Revision: $Revision: 1.3 $
        Status:           $State: Exp $
    */

    #include "sdlapplication.h"
    #include "sdlbutton.h"
    #include "sdlgradientwidget.h"
    #include "bresenham.h"

    // for simplicity I'll implement all that stuff in one file

    // a new custom widget called MyWidget

    // this widget just draws 2 lines into its drawing area:
    // from the upper left to the lower right
    // from the upper right to the lower left

    class MyWidget : public SDLGradientWidget {
    public:

        // the constructor
        MyWidget(SDLWidget* parent, SDL_Rect& r);

        // the destructor
        ~MyWidget();

    protected:

        // our custom event handler to redraw our stuff
        void eventDraw (SDL_Surface* surface, SDL_Rect* rect);

    private:

        // the color we want to draw the lines with
        SDL_Color my_color;
    };

    // implementation of MyWidget

    MyWidget::MyWidget(SDLWidget* parent, SDL_Rect& r) : SDLGradientWidget(parent, r) {
        // here we do some initialization e.g the color :)

        // the red value
        my_color.r = 200;

        // the green value
        my_color.g = 50;

        // the blue value
        my_color.b = 10;
    }

    MyWidget::~MyWidget() {
        // here we could do some cleanup
    }

    // implementation of the draw event
    // (fills the widget with some nice gfx)

    void MyWidget::eventDraw (SDL_Surface* surface, SDL_Rect* rect) {
        // first we call our base class to do it's drawing stuff
        SDLGradientWidget::eventDraw(surface, rect);

        // we draw our first line
        SDL_DrawLine(
            surface,
            rect->x ,
            rect->y,
            rect->x + rect->w -1,
            rect->y + rect->h -1,
            my_color);

        // we draw our second line
        SDL_DrawLine(
            surface,
            rect->x + rect->w -1,
            rect->y,
            rect->x ,
            rect->y + rect->h -1,
            my_color);
    }

    //  to process events we can use callback functions

    //  callbacks are defined the following:
    //  bool funcname (int id, SDLWidget* widget, unsigned long data, void *clientdata)

    //  for your convenience there is a macro that makes your live easier:
    //  PARAGUI_CALLBACK(funcname)

    PARAGUI_CALLBACK(exit_handler) {

        // we can pass in some pointer to any userdata
        // (in this case we get a pointer to the application object)
        SDLApplication* app = (SDLApplication*) clientdata;

        // exit the application eventloop
        app->Quit();

        // return true to signal that we have processed this message
        return true;
    }

    //  your main func

    int main(int argc, char* argv[]) {

        // every ParaGUI application need an application-object
        SDLApplication app;

        // every application needs a theme (the look & feel of the widgets)
        app.LoadTheme("default");

        // we must initialize the screen where we want to draw on

        // 640 - screen width
        // 480 - screen height
        // 16 - bitdepth (hicolor)
        // SDL_SWSURFACE - SDL option to generate surface in system memory

        app.InitScreen(640, 480, 16, SDL_SWSURFACE);

        // ok - now we have a nice 640x480x16 window on the screen :)

        // after that we can create some widgets

        SDL_Rect rect;
        rect.x = 260;
        rect.y = 100;
        rect.w = 120;
        rect.h = 50;

        SDLButton myButton(
                        // an optional parent widget for our button - NULL for no parent
                        NULL,
                        // the widget id (used to identify events)
                        1,
                        // the screen position where the button should appear
                        rect,
                        // some textlabel for the button
                        "Hello World!"
                        );

        // this defines our callback handler for the
        // message MSG_BUTTONCLICK,
        // we pass a pointer to the app object as userdata

        myButton.SetEventCallback(MSG_BUTTONCLICK, exit_handler, &app);

        // now we have to make the button visible

        myButton.Show();

        // here we create our custom widget

        MyWidget me(
                        // still no parent widget
                        NULL,
                        // a static function to create rects
                        SDLWidget::mkrect(260,160,120,50)
                        );

        // show me your .... lines ;-)

        me.Show();

        // Every ParaGUI application is event driven,
        // so we need a loop where
        // we process all events (like mouse handling, keystrokes,...)

        // usually this is done with SDLApplication::Run()

        app.Run();

        // this function will only exit when the application was closed

        return 0;
    }