So for a Fl_Input you can set the when() as FL_WHEN_ENTER_KEY, then if you hit 
the enter key, the callback for the input widget should run.

I tried that in a test program and it works.  Thanks!

Can you clarify; I'm not clear what you are asking here, can you outline what 
you are trying to achieve, then we can suggest some ways you might implement 
that.

I am starting with a simple program to show a whole note on a staff with a 
treble clef. The user is asked to enter the note name. The program should let 
the user know if their input was correct and display a running score in the 
window.

Here is the basic algorithm:

Display window with the following:

  Instruction header - prompts user to enter note name.
  staff and clef - (staff is drawn. clef and note are .png)

  Loop {
  note is shown on the staff - chosen randomly from a bank of locations.
  User enters note name
  Program checks user response, tabulates a score and prints a running  score 
to the window
  }

  User selects a quit button which destroys all dynamically allocated widgets.

Here is the code I have so far.  It compiles and runs with my png files, but I 
don't know how to:
1.  Get the user's input to the window instead of the console.
    I think I can send it to an output box, but I'd like to send
    it to the window via an "invisible" box  - sort of like the header.
2.  Loop the sequence. I would also like to keep the code which checks the 
answers separate from the code that implements the GUI.

#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Return_Button.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Box.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Shared_Image.H>
#include <FL/Fl_PNG_Image.H>
#include <iostream>
using namespace std;

// SIMPLE WIDGET THAT DRAWS A LINE
class DrawLINE : public Fl_Widget {
public:
    DrawLINE(int X, int Y, int W, int H, const char*L=0) : Fl_Widget(X,Y,W,H,L) 
{
    }
    void draw() {
        // DRAW BLACK LINE
        fl_color(FL_BLACK);
        fl_line_style(FL_SOLID, 2);
        int x1 = x(), y1 = y(), x2 = w(), y2 = h();
        fl_line(x1, y1, x2, y2);
    }// modified from G. Ercolano's cheatsheet (Draw an X)
}; // When this is resized it gets funky so I think I don't have it
   // quite right...

class SimpleWindow : public Fl_Window{

   public:
      SimpleWindow(int w, int h, const char* title );
      ~SimpleWindow();
      Fl_Input* inp;
      Fl_Return_Button* entr;
      Fl_Button* quit;
      Fl_Box* header;
      Fl_Box* noteBox;
      Fl_Box* clefBox;
      Fl_Box* comment;

      const char* letters;  // user response

      Fl_PNG_Image* note;
      Fl_PNG_Image* clef;

      // DrawLINE pointers for drawing the staff
      DrawLINE* line1;
      DrawLINE* line2;
      DrawLINE* line3;
      DrawLINE* line4;
      DrawLINE* line5;
      DrawLINE* vert1;
      DrawLINE* vert2;
      DrawLINE* vert3;

   private:

      static void cb_getInfo(Fl_Widget*, void*);
      inline void cb_getInfo_i();

      static void cb_quit(Fl_Widget*, void*);
      inline void cb_quit_i();
};

//----------------------------------------------------

int main (){

   SimpleWindow win(400,400,"        Treble Clef Note Identification");
   return Fl::run(); // I modified the window below from a beginner //fltk 
tutorial.
   // The problem I see is that implementation of the SimpleWindow looks
   // like function main.  I really don't want to attempt loops inside
   // a class implementation
}

//--From what I understand it is better to have children of a window
// dynamically allocated so all the info can be passed via a pointer
// and all the children are destroyed when the parent is destroyed.
// Is this a correct assumption and good programming practice?

SimpleWindow::SimpleWindow(int w, int h, const char* 
title):Fl_Window(w,h,title){

   begin();

      // Draw header
      header = new Fl_Box(100, 20, 200, 30, "Type the note name in the 
box\nbelow and hit enter.");

      // Draw Staff
      line1 = new DrawLINE(100, 100, 300, 100);
      line2 = new DrawLINE(100, 110, 300, 110);
      line3 = new DrawLINE(100, 120, 300, 120);
      line4 = new DrawLINE(100, 130, 300, 130);
      line5 = new DrawLINE(100, 140, 300, 140);
      vert1 = new DrawLINE(300,  99, 300, 141);
      vert2 = new DrawLINE(298,  99, 298, 141);
      vert3 = new DrawLINE(292,  99, 292, 141);

      fl_register_images();     // Register the images.

      // Draw clef
      clefBox = new Fl_Box(95, 80, 55, 85);
      clef    = new Fl_PNG_Image("tc75.png");
      clefBox->image(clef);

      // Draw note
      noteBox = new Fl_Box(200, 101, 30, 30);
      note    = new Fl_PNG_Image("note.png");
      noteBox->image(note);

      entr = new Fl_Return_Button(100, 300, 80, 30, "Enter");
      entr->callback( cb_getInfo, this );

      quit = new Fl_Button(250, 300, 50, 30, "&Quit");
      quit->callback(cb_quit, this);

      inp = new Fl_Input(200, 190, 30, 30);

   end();
   show();
}

//----------------------------------------------------

SimpleWindow::~SimpleWindow(){}

//----------------------------------------------------

void SimpleWindow::cb_getInfo(Fl_Widget* o, void* v) {

  ( (SimpleWindow*)v )->cb_getInfo_i();
}

void SimpleWindow::cb_getInfo_i() {

   letters = inp->value();
   cout << "You typed " << letters << endl;

}

//----------------------------------------------------

void SimpleWindow::cb_quit(Fl_Widget* , void* v) {

   ( (SimpleWindow*)v )->cb_quit_i();
}

void SimpleWindow::cb_quit_i() {

    hide();
}

I am open to any and all suggestions and I thank you for your time!
All best wishes,
Edgar Crockett


_______________________________________________
fltk mailing list
fltk@easysw.com
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to