Pagina 1 di 1

[Risolto] FLTK : FL_Browser e numero colonne

Inviato: mar 2 ago 2011, 17:44
da ccts2002
Salve a tutti!
sto provando a programmare con le FLTK, che mi hanno ispirato in quanto l'eseguibile che risulta è veramente "light".
premetto che sono in ambiente windows (in ufficio dobbiamo usare questo e nient'altro).
la mia idea è quella di provare un pò i widget che queste librerie propongono nel tempo libero in modo da essere più padrone delle librerie e poter veramente programmare qualcosa di utile; per ora mi stavo occupando di Fl_Browser, che, dagli esempi del manuale e del sito di Greg Ercolano, può visualizzare sia un elenco che una specie di tabella.
ho creato una sottoclasse di Fl_Window e all'interno di questa ho inserito tutti i Widget che voglio utilizzare. i file creati sono:
main.cc

Codice: Seleziona tutto

#include "MyWindow.h"

int  main(int  argc,  char  **argv)  {
 MyWindow  *window  =  new  MyWindow(950,300, "Cone Frustum Characteristics");
 window->show();
 return  Fl::run();
}
MyWindow.h

Codice: Seleziona tutto

#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 <FL/Fl_Box.H>
#include <FL/Fl_Menu_Bar.H>
#include <FL/Fl_Tree.H>
#include <FL/Fl_Browser.H>

#ifndef MYWINDOW
#define MYWINDOW

class MyWindow : public Fl_Window {
 protected:
  Fl_Menu_Bar * m;
  Fl_Box      * description;
  Fl_Button   * button;
  Fl_Input    * inp_diam_max  ;
  Fl_Input    * inp_diam_min  ;
  Fl_Input    * inp_thickness ;
  Fl_Input    * inp_height    ;
  Fl_Input    * inp_gravity   ;
  Fl_Input    * inp_dens_hull ;
  Fl_Input    * inp_dens_water;
  Fl_Output   * out_vol_hull;
  Fl_Output   * out_vol_buoy;
  Fl_Output   * out_vol_ball;
  Fl_Output   * out_mass;
  Fl_Output   * out_buoyancy;
  Fl_Output   * out_ballast;
  Fl_Browser  * listBrowser;
  Fl_Tree     * treeBrowser;

  friend void compute_cone_characteristics (Fl_Widget * , void * );
 public:
  MyWindow( int h, int w, const char * t);

};

#endif
e MyWindow.cc

Codice: Seleziona tutto

#include "MyWindow.h"
//#include "MyWindow_callback.h"


MyWindow::MyWindow( int h, int w, const char * t) : Fl_Window(h,w,t) {
 description =  new  Fl_Box (150,  25, 250, 30, "Cone Frustum Characteristics");
 description->box(FL_BORDER_BOX);

 Fl_Menu_Item menuitems[] = {
  { "&File",              0, 0, 0, FL_SUBMENU },
    { 0 },

  { "&Edit", 0, 0, 0, FL_SUBMENU },
//    { "&Compute",    FL_CTRL + 'c', (Fl_Callback *) compute_cone_characteristics },
    { 0 },

  { "&Help", 0, 0, 0, FL_SUBMENU },
    { "&About...",       FL_CTRL + 'a', 0},
    { 0 },

  { 0 }
};

 m = new Fl_Menu_Bar(0, 0, 850, 20);
 m->copy(menuitems, this );

 inp_diam_max   =  new  Fl_Input (150,  70,  100,  25,  "Diam. Max : ");
 inp_diam_min   =  new  Fl_Input (150, 100,  100,  25,  "Diam. Min : ");
 inp_thickness  =  new  Fl_Input (150, 130,  100,  25,  "Thickness : ");
 inp_height     =  new  Fl_Input (150, 160,  100,  25,  "Height : ");
 inp_gravity    =  new  Fl_Input (150, 190,  100,  25,  "Gravity Accel. : ");
 inp_dens_hull  =  new  Fl_Input (150, 220,  100,  25,  "Density Material : ");
 inp_dens_water =  new  Fl_Input (150, 250,  100,  25,  "Density Water : ");

 out_vol_hull  =  new  Fl_Output(400, 100,  100,  25,  "Vol. Shell : ");
 out_vol_buoy  =  new  Fl_Output(400, 130,  100,  25,  "Vol. Buoyancy : ");
 out_vol_ball  =  new  Fl_Output(400, 160,  100,  25,  "Vol. Ballast : ");
 out_mass      =  new  Fl_Output(400, 190,  100,  25,  "Mass : ");
 out_buoyancy  =  new  Fl_Output(400, 220,  100,  25,  "Buoyancy : ");
 out_ballast   =  new  Fl_Output(400, 250,  100,  25,  "Ballast : ");

 out_vol_hull -> labelcolor(FL_RED);
 out_vol_buoy -> labelcolor(FL_RED);
 out_vol_ball -> labelcolor(FL_RED);
 out_mass     -> labelcolor(FL_RED);
 out_buoyancy -> labelcolor(FL_RED);
 out_ballast  -> labelcolor(FL_RED);

 out_vol_hull -> align(FL_ALIGN_LEFT);
 out_vol_buoy -> align(FL_ALIGN_LEFT);
 out_vol_ball -> align(FL_ALIGN_LEFT);
 out_mass     -> align(FL_ALIGN_LEFT);
 out_buoyancy -> align(FL_ALIGN_LEFT);
 out_ballast  -> align(FL_ALIGN_LEFT);

 out_vol_hull -> textcolor(FL_RED);
 out_vol_buoy -> textcolor(FL_RED);
 out_vol_ball -> textcolor(FL_RED);
 out_mass     -> textcolor(FL_RED);
 out_buoyancy -> textcolor(FL_RED);
 out_ballast  -> textcolor(FL_RED);
 //
 inp_diam_max  ->value("3.2");
 inp_diam_min  ->value("0.8256");
 inp_thickness ->value("0.01");
 inp_height    ->value("1.2");
 inp_gravity   ->value("9.806");
 inp_dens_hull ->value("7.85");
 inp_dens_water->value("1.025");
 //
 button  =  new  Fl_Button(400,  70,  100,  25,  "Compute");
// button->callback(  compute_cone_characteristics , this );

 treeBrowser = new Fl_Tree(550, 70, 125, 205);
 treeBrowser->root_label("MyModel");
 treeBrowser->begin();
 treeBrowser->add("/Node");
 treeBrowser->add("/Beam");
 treeBrowser->add("/Section");
 treeBrowser->add("/Material");
 treeBrowser->end();

 listBrowser = new Fl_Browser(700,70,200,205); 
 int widths[] = { 50,  40,  40, 40,0 };               // widths for each column
 listBrowser->column_widths(widths);
 listBrowser->column_char(',');                          // tabs as column delimiters
 listBrowser->type(FL_MULTI_BROWSER);
 listBrowser->add("TT,COM3,COM4,COM7,COM9");             // lines of tab delimited data
 listBrowser->add("tt,t   ,t   ,t   ,t   ");
 listBrowser->add("tt,tusr,tusr,tusr,tusr");
 listBrowser->add("tt,tsbi,tsbi,tsbi,tsbi");
 listBrowser->add("tt,tsbi,tsbi,tsbi,tsbi");
 listBrowser->add("tt,tsbi,tsbi,tsbi,tsbi");
};
Compilando il tutto ho un comportamento "strano" di FL_Browser...in pratica non riesco a visualizzare tutte le colonne, ma solo la prima.
La cosa ancora più strana è che spostando il codice relativo al Fl_Browser all'interno del main() subito dopo la dichiarazione di * window... il tutto si vede correttamente...

riuscite a capire cosa stia succedendo? io ci ho sbattuto la testa tutto oggi pomeriggio e ancora non ne sono venuto a capo...e il capo ora mi fa male! :)

grazie in anticipo!

ciao
Claudio

Re: FLTK : FL_Browser e numero colonne

Inviato: mer 3 ago 2011, 12:13
da ccts2002
Rieccomi!
facendo un pò di printout al sorgente di Fl_Browser.cxx ho capito dove sta il problema e anche come risolverlo...
in pratica il problema era nell'array widths[] e al fatto che fosse un array globale nel caso in cui inserivo la definizione di Fl_Browser nel main, mentre diventava locale nel caso in cui la definizione di Fl_Browser fosse fatta nel costruttore di MyWindow: in quest'ultimo caso una volta eseguita la funzione costruttore la parte di memoria contenente la larghezza delle colonne (e quindi anche il suo numero) veniva riutilizzata e quindi Fl_Browser non aveva più modo di capire come le colonne fossero gestite. Spero di essere stato chiaro, in caso cercherò di spiegarmi meglio!
per quanto riguarda la soluzione, ho risolto creando una mia classe derivata di Fl_Browser che avesse una copia locale dell'array contenente le larghezze, oltre ad avere una variabile che definisce il numero di colonne.
di seguito il codice.
MyBrowser.h

Codice: Seleziona tutto

#include <FL/Fl.H>
#include <FL/Fl_Browser.H>

#ifndef MYBROWSER
#define MYBROWSER

class MyBrowser : public Fl_Browser {
 protected:
  int column_number_;
  int * column_widths_;
 public:
  MyBrowser (int X, int Y, int W, int H, const char *L = 0 ) ;
  void column_number ( int d) ; 
  int column_number ( ) ;
  int * column_widths() const ;
  void column_widths(const int* arr) ;
};

#endif
MyBrowser.cc

Codice: Seleziona tutto

#include "MyBrowser.h"

MyBrowser::MyBrowser (int X, int Y, int W, int H, const char *L = 0)
          : Fl_Browser( X,  Y,  W, H, L ) {
 column_widths_ = NULL; 
 column_number (1); 
 column_widths_[0] = 0;
};

void MyBrowser::column_number ( int d) { 
 column_number_ = d; 
 delete[] column_widths_;
 column_widths_ = new int[d];
 Fl_Browser::column_widths(column_widths_);
};

int MyBrowser::column_number ( ) { return column_number_; };
  /**
    Gets the current column width array.
    This array is zero-terminated and specifies the widths in pixels of
    each column. The text is split at each column_char() and each part is
    formatted into it's own column.  After the last column any remaining
    text is formatted into the space between the last column and the
    right edge of the browser, even if the text contains instances of
    column_char() .  The default value is a one-element array of just
    a zero, which means there are no columns.
    \see column_char(), column_widths()
  */
int* MyBrowser::column_widths() const { return column_widths_; }

/**
  Sets the current array to \p arr.  Make sure the last entry is zero.
  \see column_char(), column_widths()
*/
void MyBrowser::column_widths(const int* arr) {
 for ( int i = 0 ; i < column_number() ; i++ )
  column_widths_[i] = arr[i];
}
se qualcuno volesse ulteriori chiarimenti sono a disposizione!

ciao
Claudio