Sunday, September 25, 2011

C++ FLTK ADDING BUTTONS TO A WINDOW TUTORIAL









REVISED: Friday, March 22, 2013




CONTENTS:
I.    INTRODUCTION
II.  EXAMPLE 1 - BLANK WINDOW
III. EXAMPLE 2 - ADDING A BUTTON
IV. EXAMPLE 3 - ADDING A BUTTON CALLBACK
V. EXAMPLE 4 - PASSING USER DATA

YOU WILL LEARN HOW TO CODE A C++ FLTK:
1. Blank window.
2. Window button.
3. userdata.

I. INTRODUCTION


Hello; nice to meet you! Welcome to the “C++ FLTK ADDING BUTTONS TO A WINDOW TUTORIAL.”

This tutorial is a very brief overview of information presented by Dr. Bjarne Stroustrup in his book “Programming Principles and Practices Using C++,” Addison-Wesley 2009, ISBN 978-0321543721.

The web site for his book and the appropriate FLTX header files is:

http://www.stroustrup.com/Programming/

II. EXAMPLE 1 - BLANK WINDOW


Please copy and paste Example 1 into your IDE then build and debug.

//***********************************
//Exampe 1
//Blank Window
//***********************************
#include <Fl/Fl.H>            
//Required by all FLTK programs.
#include <Fl/Fl_window.H>     
//Required for window class.

int main()
{
    Fl_Window win(600,400);   
//Creates window width 600 height 400.
    win.show();                            
//Tells FLTK to show the window.
    return(Fl::run());                    
//Returns value of FLTK command loop, //this function returns only when all
//windows are closed.
}


Example 1 creates an empty window with no window title and no buttons.

There is one include file for every class in FLTK. For example:

#include <Fl/Fl_window.H>

Is the include file for the Fl_Window class.

In the following statement:

Fl_Window win(600,400);


win is the object name instantiated by the class window.

When an object of the class is instantiated the parentheses following the object name enclose the arguments required by the class constructor. In this case the first argument is the width and the second argument is the height. The third argument is an optional title character string.

return(Fl::run());


Returns the value of FLTK command loop, this function returns only when all windows are closed.

III. EXAMPLE 2 - ADDING A BUTTON


Please copy and paste Example 2 into your IDE then build and debug.

//***********************************
//Exampe 2
//Adding a button
//***********************************
#include <Fl/Fl.H>                     
//Required by all FLTK programs.
#include <Fl/Fl_window.H>      
//Required for window class.
#include <FL/FL_Button.H>     
//Required for button class.

int main()
{
    Fl_Window win(600,400,"FLTK is easy to learn and fun to use.");   
//Creates window width 600 height 400.
    Fl_Button button(5,5,75,30,"Click Me");  
//Button arguments starting
//point(x,y),width,heigth,"label."
    win.show();                                                  //Tells FLTK to show the window.
    return(Fl::run());                                          //Returns value of FLTK
//command loop, this
//function returns only when all
//windows are closed.
}


Below the window definition we added a call for a button.

Fl_Button button(5,5,75,30,"Click Me");


The button is a rectangle. A rectangle is defined by a (x,y) starting point for its top left corner of the rectangle and its width and its height. The first two arguments are the top left corner (x,y) starting point inside of the window. The third and fourth arguments are the width and height respectively. The fifth argument is a character string title for the button.

Since we are using the Button class we added an include file for button:

#include <FL/FL_Button.H>

And, we added a title to the window.

Fl_Window win(600,400,"FLTK is easy to learn and fun to use.");

IV. EXAMPLE 3 - ADDING A BUTTON CALLBACK


Please copy and paste Example 3 into your IDE then build and debug.

//***********************************
//Exampe 3
//Adding a button callback.
//***********************************
#include <Fl/Fl.H>                     
//Required by all FLTK programs.
#include <Fl/Fl_window.H>      
//Required for window class.
#include <FL/FL_Button.H>     
//Required for button class.
#include <stdio.h>                      
//Required for display.

void My_Callback(Fl_Widget*w, void* userdata)
{
     fprintf(stderr, "Button works!\n");
}

int main()
{
    Fl_Window win(600,400,"FLTK is fun to learn and easy to use.");   
//Creates window width 600 height 400.
    Fl_Button button(5,5,75,30,"Click Me");  
//Button arguments starting
//point(x,y),width,heigth,"label."
    button.callback(My_Callback);
    win.show();                
//Tells FLTK to show the window.
    return(Fl::run());        
//Returns value of FLTK
//command loop, this
//function returns only when
//all windows are closed.
}


We want the button to do something. To make the button do something we have to add a callback.

void My_Callback(Fl_Widget*w, void* userdata)
{
     fprintf(stderr, "Button works!\n");
}


Callbacks in FLTK always return a void. 

We declared the callback named My_Callback. The first two arguments are a widget pointer, which is a pointer to the widget that invoked the callback, and a void pointer to userdata which can be any kind of data that you want.


Below the button definition we attach the callback to the button.

button.callback(My_Callback);


Now when the button is clicked the callback will display on the black background window, "FLTK is fun to learn and easy to use."

To get the display to work we added:

#include <stdio.h>

V. EXAMPLE 4 - PASSING USER DATA


Please copy and paste Example 4 into your IDE then build and debug.

//***********************************
//Exampe 4
//Passing userdata
//***********************************
#include <Fl/Fl.H>                     
//Required by all FLTK programs.
#include <Fl/Fl_window.H>      
//Required for window class.
#include <FL/FL_Button.H>     
//Required for button class.
#include <stdio.h>                      
//Required for display.

void My_Callback(Fl_Widget*w, void* userdata)
{
     fprintf(stderr, "Button Clicked! Userdata passed is %d\n", (int)userdata);
}

int main()
{
    Fl_Window win(600,400,"FLTK is fun to learn and easy to use.");   
//Creates window width 600 height 400.
    Fl_Button button(5,5,75,30,"Click Me");  
//Button arguments starting
//point(x,y),width,heigth,"label."
    button.callback(My_Callback, (void*)54321);
    win.show();                                                  //Tells FLTK to show the window.
    return(Fl::run());                                          //Returns value of FLTK
//command loop, this
//function returns only when all
//windows are closed.
}


We want to pass userdata. userdata is passed as an optional second argument to the callback. The userdata can be any type of data you want as long as it is one piece of data that can be cast to a void pointer.

button.callback(My_Callback, (void*)54321);


When you push the button, it calls the callback function, and passes the 54321 data as the userdata and the function can do with that 54321 userdata whatever it wants.

void My_Callback(Fl_Widget*w, void* userdata)
{
     fprintf(stderr, "Button Clicked! Userdata passed is %d\n", (int)userdata);
}


In our example the 54321 userdata is printed to the black background window when the button is clicked.

You might have to click and drag the grey foreground window out of the way to see the black background window. Remember the display will be on the black background window not the grey foreground window.

YOU HAVE LEARNED HOW TO CODE A C++ FLTK:
1. Blank window.
2. Window button.
3. Userdata.

Elcric Otto Circle




-->

-->

-->




How to Link to My Home Page

It will appear on your website as:
"Link to ELCRIC OTTO CIRCLE's Home Page"




C++ FLTK GRAPHING ALGEBRAIC FUNCTIONS TUTORIAL









REVISED: Friday, March 22, 2013




CONTENTS:
I.    INTRODUCTION
II.  HORIZONTAL LINE
III. SLOPING LINE
IV. PARABOLA

YOU WILL LEARN HOW TO GRAPH THE FOLLOWING ALGEBRAIC FUNCTIONS USING C++ AND FLTK:
1. HORIZONTAL LINE
2. SLOPING LINE
3. PARABOLA

I. INTRODUCTION


Welcome to the “C++ FLTK GRAPHING ALGEBRAIC FUNCTIONS TUTORIAL.”

This tutorial is a very brief overview of information presented by Dr. Bjarne Stroustrup in his book “Programming Principles and Practices Using C++,” Addison-Wesley 2009, ISBN 978-0321543721.

The web site for his book and the appropriate FLTX .h header files and .cpp files is:

http://www.stroustrup.com/Programming/


Please copy and paste the following example program into your IDE; then build and debug the example program.

//***********************************
//C++ FLTK GRAPHING ALGEBRAIC
//FUNCTIONS TUTORIAL
//***********************************
#include "Simple_window.h"
#include "Graph.h"

double one(double)
{
    return 1;
}

double slope(double x)
{
    return x/2;
}

double square(double x)
{
    return x*x;
}

int main( int argc, char* argv[] )
{
    using namespace Graph_lib;
    Point tl(100, 100);

    const int xmax = 600;
    const int ymax = 400;

    const int x_orig = xmax/2;
    const int y_orig = ymax/2;
    const Point orig(x_orig,y_orig);

    const int r_min = -10;
    const int r_max = 11;

    const int n_points = 400;

    const int x_scale = 30;
    const int y_scale = 30;
    Simple_window win(Point(100,100),xmax,ymax,"FUNCTION GRAPHING");

    Function s(one,r_min,r_max,orig,n_points,x_scale,y_scale);
    Function s2(slope,r_min,r_max,orig,n_points,x_scale,y_scale);
    Function s3(square,r_min,r_max,orig,n_points,x_scale,y_scale);

    win.attach(s);
    win.attach(s2);
    win.attach(s3);
   
    Text ts(Point(100,y_orig-40),"one");
    Text ts2(Point(100,y_orig+y_orig/2-20),"x/2");
    Text ts3(Point(x_orig-100,20),"x*x");
    win.set_label("Function Graphing: Label Functions");
    win.wait_for_button();

    win.attach(ts);
    win.attach(ts2);
    win.attach(ts3);
    win.wait_for_button();

    const int xlength = xmax-40;
    const int ylength = ymax-40;

    Axis x(Axis::x,Point(20,y_orig),xlength,xlength/x_scale,"one notch == 1");
    Axis y(Axis::y,Point(x_orig,ylength+20),
        ylength,ylength/y_scale,"one notch == 1");

    x.set_color(Color::dark_red);
    y.set_color(Color::dark_red);

    win.attach(x);
    win.attach(y);

    win.wait_for_button();
}

II. HORIZONTAL LINE


A line parallel to the x-axis is called a horizontal line. A horizontal line is parallel to the x-axis because the y value never changes.

We get a horizontal line by graphing the following function:

double one(double)
{
    return 1;
}


The line is defined by (x,y) == (x,1) for all x. In other words, we get the y value 1 for every x passed as an argument to the function one().

The following code specifies how it is to be drawn in the window:

Function s(one,r_min,r_max,orig,n_points,x_scale,y_scale);


The function specifies how its first argument, a function of one double argument returning a double, is to be drawn in the window.

The second argument and the third argument give the range of x, the argument to the function to be graphed.

The fourth argument, orig, tells the function where origin (0,0) is to be located within the window.

The remaining three arguments are default arguments. The function constructor arguments n_points, xscale and yscale were given the following initializers in the declaration. The default argument values are used if the caller does not specify values.

const int n_points = 400;

const int x_scale = 30;
const int y_scale = 30;

The graph label is as follows:

Text ts(Point(100,y_orig-40),"one");


The following code attaches the function and the graph label to win.

win.attach(s);
win.attach(ts);

III. SLOPING LINE


The slope of a line is referred to as the rise over the run, or given two points on the line, the change in the y coordinates over the change in x coordinates.

We get a sloping line by graphing the following function:

double slope(double x)
{
    return x/2;
}


The line is defined by (x,y) == (x,x/2). For every x we get the y value x/2.

The point where the two lines cross is (2,1).

The following code specifies how it is to be drawn in the window:

Function s2(slope,r_min,r_max,orig,n_points,x_scale,y_scale);


The function specifies how its first argument, a function of one double argument returning a double, is to be drawn in the window.

The second argument and the third argument give the range of x, the argument to the function to be graphed.

The fourth argument, orig, tells the function where origin (0,0) is to be located within the window.

The remaining three arguments are default arguments. The function constructor arguments n_points, and xscale were given the following initializers in the declaration. The default argument values are used if the caller does not specify values.

const int n_points = 400;

const int x_scale = 30;

The graph label is as follows:

Text ts2(Point(100,y_orig+y_orig/2-20),"x/2");


The following code attaches the function and the graph label to win.

win.attach(s2);
win.attach(ts2);

IV. PARABOLA


We get a parabola by graphing the following function:

double square(double x)
{
    return x*x;
}


The line is defined by (x,y) == (x,x*x). The lowest point where the parabola touches the sloping line is (0,0). The parabola is symmetric on the y axis.

The following code specifies how it is to be drawn in the window:

Function s3(square,r_min,r_max,orig,n_points,x_scale,y_scale);


The function specifies how its first argument, a function of one double argument returning a double, is to be drawn in the window.

The second argument and the third argument give the range of x, the argument to the function to be graphed.

The fourth argument, orig, tells the function where origin (0,0) is to be located within the window.

The remaining three arguments are default arguments. The function constructor arguments n_points were given the following initializer in the declaration. The default argument value is used if the caller does not specify a value.

const int n_points = 400;

The graph label is as follows:

Text ts3(Point(x_orig-100,20),"x*x");


The following code attaches the function and the graph label to win.

win.attach(s3);
win.attach(ts3);

YOU HAVE LEARNED HOW TO GRAPH THE FOLLOWING ALGEBRAIC FUNCTIONS USING C++ AND FLTK:
1. HORIZONTAL LINE
2. SLOPING LINE
3. PARABOLA

Elcric Otto Circle






-->

-->

-->




How to Link to My Home Page

It will appear on your website as:
"Link to ELCRIC OTTO CIRCLE's Home Page"




C++ FLTK BUTTONS TUTORIAL









REVISED: Friday, March 22, 2013




CONTENTS:
I.    INTRODUCTION
II.   WIDGET
III.  EXAMPLE 1 - BUTTON 
IV. EXAMPLE 2 - BUTTON
V.  EXAMPLE  3 - BUTTON
VI. VOID* POINTERS

YOU WILL LEARN:
1. FLTK widgets.
2. FLTK buttons.

I. INTRODUCTION


Welcome to the “C++ FLTK Buttons Tutorial.”

II. WIDGET


A widget is a control that defines interaction between a program and a graphical user interface (GUI). A button is a widget that invokes a callback when it is clicked. A menu is a vector of buttons. In_box and Out_box are two Widgets for getting text into and out of your program.

A widget has two functions:

1. show() makes the Widget visible.

A Widget starts out visible.

2. hide() makes the Widget invisible.

III. EXAMPLE 1 - BUTTON 


Copy and past the following FLTK button example program into your integrated development environment (IDE), then build, and debug the program:

//***********************************
//C++ FLTK Buttons Tutorial
//Example 1 - Button 
//***********************************
#include <iostream>
#include <FL/Fl.H>
#include <FL/Fl_window.H>
#include <FL/Fl_Button.H>
using namespace std;

void button_cb( Fl_Widget*, void* );

void make_window()
{
   Fl_Window* win= new Fl_Window( 500,400, "C++ FLTK Buttons Tutorial - Example 1" );
   win->begin();
      Fl_Button* but = new Fl_Button( 0, 0, 40, 40, "ON" );
   win->end();
   but -> callback( ( Fl_Callback* ) button_cb );
   win->show();
}

void button_cb( Fl_Widget* obj , void* )
{
   obj->label( "OFF" );
 
   obj->resize( 0,0,40,40 );
   obj->redraw();
}

int main( int argc, char* argv[] )
{
   make_window();
   return Fl::run();
}

Fl_Window* win= new Fl_Window( 500,400, "C++ FLTK Buttons Tutorial - Example 1" );


Creates a pointer to the new window object setting the width, height and the name in the title bar. Keyword new allocates heap memory for the object.

win->begin();


States until you reach win->end() new widgets will be added as children to the current Fl_window.

Fl_Button* but = new Fl_Button( 0, 0, 40, 40, "ON" );


Creates a button, which is a child of the parent window, with input parameters (x, y, width, height, label) where x, y are the position in pixels relative to the top left corner (0,0).

The button is the first child of the window with index 0. Only objects derived from Fl_Group have this child parent relationship.

Deleting the parent, Fl_Window, will automatically delete all the children of the window. For example, if we delete “win,” “but” will be deleted automatically.

win->end();

Sets the current group to the parent of the window.

but -> callback( ( Fl_Callback* ) button_cb );


button_cb” is the name of our callback function. It is generally accepted programming practice to start or end callback function names with ”cb.”

Callbacks are a means of executing code when an event occurs. In order to use its base classes callback member function, “but” points to an Fl_Button, derived from Fl_Widget.

win->show();


Makes the window on the screen visible.

void button_cb( Fl_Widget* obj , void* )


Declares the callback function and since we passed null by default we do not need void*; however, we used it as a placeholder anyway.

The only two widget members that automatically call redraw are label() and value(). A manual call of redraw is required by everything else.

obj->resize( 0,0,40,40 );

Resizes the button.

obj->redraw();

Redraws the widget.

return Fl::run();


The function run() returns 0 and ends the program.

IV. EXAMPLE 2 - BUTTON 


Copy and past the following FLTK example program into your IDE, then build, and debug the program:

//***********************************
//C++ FLTK Buttons Tutorial
//Example 2 - Button 
//***********************************
#include <iostream>
#include <FL/Fl.H>
#include <FL/Fl_window.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Output.H>
#include <cstdlib>
using namespace std;

void copy_cb( Fl_Widget*, void* );
void close_cb( Fl_Widget*, void* );
void make_window();

int main( int argc, char* argv[] )
{
   make_window();
   return Fl::run();
}

void make_window()
{
   Fl_Window* win= new Fl_Window(600,250, "C++ FLTK Buttons Tutorial - Example 2");

   win->begin();  
      Fl_Button*  copy = new Fl_Button( 350, 0,  70, 30, "C&opy" ); 
//child 0
      Fl_Button* close = new Fl_Button( 430, 0,  70, 30, "&Quit" );   
//child 1
      Fl_Input*    inp = new Fl_Input( 20, 0, 140, 30, "In" );       
//child 2
      Fl_Output*    out = new Fl_Output( 200, 0, 140, 30, "Out" );  
//child 3
   win->end();

   copy->callback( (Fl_Callback*) copy_cb );
   close->callback( (Fl_Callback*) close_cb);
   win->show();
 }

void copy_cb( Fl_Widget* obj , void* )
{
   Fl_Button* button=(Fl_Button*)obj;
   const char* temp;
   temp = (  (Fl_Input*)(button->parent()->child(2))  )->value();
   (  (Fl_Output*)(button->parent()->child(3))  )->value(temp);
}

void close_cb( Fl_Widget* obj, void*)
{
   exit(0);
}


The copy and Quit buttons can be invoked by pressing ALT+c and ALT+q. Placing an "&" in front of the letter in the label parameter in the constructor achieved this form of invoking.

Communicating widgets is demonstrated when "Copy" is pressed and the program copies whatever is in "In" to "Out."

void copy_cb( Fl_Widget* obj , void* )
{
   Fl_Button* button=(Fl_Button*)obj;


obj” is an Fl_Widget input parameter and “copy_cb” is an Fl_Button callback function; therefore, “obj” refers to an Fl_Button. We cast “obj” to the Fl_Button pointer called “button.”

temp = (  (Fl_Input*)(button->parent()->child(2))  )->value();
(  (Fl_Output*)(button->parent()->child(3))  )->value(temp);


A temporary variable temp is set to the value of the Fl_Output widget.

V.  EXAMPLE 3 - BUTTON


Copy, past and debug the following FLTK example program. We will use it to see how call backs are done in classes:

//***********************************
//C++ FLTK Buttons Tutorial
//Example 3 - Button 
//***********************************
#include <iostream>
#include <FL/Fl.H>
#include <FL/Fl_window.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Output.H>
#include <cstdlib>
using namespace std;
 
class SimpleWindow : public Fl_Window{

   public:
      SimpleWindow( int w, int h, const char* title );
      ~SimpleWindow();
      Fl_Button* copy;
      Fl_Button* quit;
      Fl_Input* inp;
      Fl_Output* out;
   
   private:
      static void cb_copy( Fl_Button*, void* );
      inline void cb_copy_i( Fl_Button*, void* );
 
      static void cb_quit( Fl_Button*, void* );
      inline void cb_quit_i( Fl_Button*, void* );
};

int main( int argc, char* argv[] )
{
   SimpleWindow win( 600,250,"C++ FLTK Buttons Tutorial - Example 3" );
   return Fl::run();
}

SimpleWindow::SimpleWindow( int w, int h, const char* title ):Fl_Window( w,h,title )
{
  begin();
      copy = new Fl_Button( 375, 0,  70, 30, "C&opy" );
      copy->callback(( Fl_Callback*)cb_copy, this );
     
      quit = new Fl_Button( 450, 0,  70, 30, "&Quit" );
      quit->callback(( Fl_Callback*)cb_quit, this );
   
      inp = new Fl_Input( 40, 0, 140, 30, "Input:" );
      out = new Fl_Output( 230, 0, 140, 30, "Output:" );
   end();
   resizable( this );
   show();
}

SimpleWindow::~SimpleWindow()
{

}

void SimpleWindow::cb_copy( Fl_Button* obj, void* v )
{
   SimpleWindow* T=( SimpleWindow* )v;
   T->cb_copy_i(obj,v);
}

void SimpleWindow::cb_copy_i( Fl_Button* , void* )
{
   out->value( inp->value() );
}

void SimpleWindow::cb_quit( Fl_Button*obj , void* v )
{
   SimpleWindow* T=( SimpleWindow* )v;
   T->cb_quit_i( obj,v );
}

void SimpleWindow::cb_quit_i( Fl_Button* , void* )
{
   exit(0);
}


Callbacks in a class can only be static.

The get/set functions are overloaded with respect to their return and input parameters.

Get functions have no input parameter. inp->value() gets or returns the value of the const char* widget. The out->value(const char*) sets the value of the outobject.


The “this” pointer is implicit; therefore, you do not have to put a pointer in front of begin(), end(), show() etc.

copy->callback(( Fl_Callback*)cb_copy, this );

Utilizes the user data void*.


The address of the class instance () is passed by the “this” pointer and provides access to the entire class in the callback.

VI. VOID* POINTERS


void* is used to transmit an address between pieces of code that do not know each others type.

A pointer that can point to anything is a void* pointer. A void* pointer has no type; therefore, casting such as a static_cast explicit type conversion is used in the callback function.

Void pointers do not know the size of the object to which they are pointing, they just contain the address; therefore, a void* can never be dereferenced.

YOU HAVE LEARNED:
1. FLTK widgets.
2. FLTK buttons.

Elcric Otto Circle




-->

-->

-->




How to Link to My Home Page

It will appear on your website as:
"Link to ELCRIC OTTO CIRCLE's Home Page"