Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

ndk++.h

Go to the documentation of this file.
00001 // * This makes emacs happy -*-Mode: C++;-*-
00002 /****************************************************************************
00003  * Copyright (c) 2002 Fabrica de Software XXI SRL - info@lafabrica.com.ar   *
00004  * Copyright (c) 2002 RaqLink SA - info@raqlink.com                         *
00005  *                                                                          *
00006  * Permission is hereby granted, free of charge, to any person obtaining a  *
00007  * copy of this software and associated documentation files (the            *
00008  * "Software"), to deal in the Software without restriction, including      *
00009  * without limitation the rights to use, copy, modify, merge, publish,      *
00010  * distribute, distribute with modifications, sublicense, and/or sell       *
00011  * copies of the Software, and to permit persons to whom the Software is    *
00012  * furnished to do so, subject to the following conditions:                 *
00013  *                                                                          *
00014  * The above copyright notice and this permission notice shall be included  *
00015  * in all copies or substantial portions of the Software.                   *
00016  *                                                                          *
00017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
00018  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
00019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
00020  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
00021  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
00022  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
00023  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
00024  *                                                                          *
00025  * Except as contained in this notice, the name(s) of the above copyright   *
00026  * holders shall not be used in advertising or otherwise to promote the     *
00027  * sale, use or other dealings in this Software without prior written       *
00028  * authorization.                                                           *
00029  ****************************************************************************/
00030 
00031 /****************************************************************************
00032  *  Author Miguel Pinkas <miguel@lafabrica.com.ar>                          *
00033  ****************************************************************************/
00034 #if !defined(__NDK_NCURSES__)
00035 #define __NDK_NCURSES__
00036 #include <cursesapp.h>
00037 #include <cursesm.h>
00038 #include <cursesf.h>
00039 #include <vector>
00040 #include <string>
00041 #include <fstream>
00042 #include <typeinfo>
00043 using namespace std;
00044 
00045 #if HAVE_LIBC_H
00046 #  include <libc.h>
00047 #endif
00048 
00049 #include "dlgdefines.h"
00050 
00051 namespace NDK_XX {
00052 
00053 ofstream &get_logfile();
00054 
00055 /************************************************************************
00056 *   class NDKMenuItem                                                   *
00057 *   A derivative of NCursesMenuItem to add some nice stuff              *
00058 *                                                                       *
00059 ************************************************************************/
00060 class NDKMenuItem : public NCursesMenuItem
00061 {
00062   friend class NDKMenu;
00063 public:
00064     NDKMenuItem(const char *p_name= 0,const char *p_descript=0 )
00065         :NCursesMenuItem(   p_name ,p_descript){
00066         
00067     };
00068     
00069     ///Access to the underlying item;
00070     ITEM *get_curses_item()const{return item;}
00071     
00072     ///Access to our parent C++ menu object
00073     NDKMenu *get_menu() const { return pMenu;}
00074 protected:
00075 
00076     ///The C++ menu object we belong to
00077     NDKMenu *pMenu;
00078 
00079 };
00080 
00081 typedef vector<NCursesMenuItem *> ListOfItems;
00082 
00083 
00084 /************************************************************************
00085 *   class NDKMenu                                                       *
00086 *   A derivative of NCursesMenu to add some nice stuff                  *
00087 *                                                                       *
00088 ************************************************************************/
00089 class NDKMenu : public NCursesMenu
00090 {
00091 public:
00092     // Make a menu with a window of this size.
00093     NDKMenu (ListOfItems &items, 
00094         int  lines, 
00095         int  cols, 
00096         int  begin_y = 0, 
00097         int  begin_x = 0,
00098         bool framed=FALSE,        
00099         bool own_items=FALSE);  // Autocleanup of Items?
00100 
00101     NDKMenu( int  lines, int  cols, int  begin_y = 0, int  begin_x = 0
00102                                 ,bool framed=FALSE); 
00103 
00104 
00105     ///We use the next three to autosize menubars
00106     int get_itemwidth() const   { return menu? menu->itemlen + menu->spc_cols:0;} 
00107     int get_itemmarklen() const { return menu? menu->marklen:0;} 
00108     int get_spcrows() const     { return menu? menu->spc_rows:0;} 
00109 
00110     
00111     // Do that silly traversal with a real iterator...
00112     static short count_items(NCursesMenuItem* nitems[]) {
00113         int itemCount = 0;
00114         for (int lcv=0; nitems && nitems[lcv]->name(); ++lcv){
00115             ++itemCount;
00116         }
00117         return itemCount;
00118     }
00119     
00120     ///Hide good ol' pointers from here on...
00121     void setItems(ListOfItems &items){NCursesMenu::setItems(items.begin()); }
00122 
00123     ///Hide good ol' pointers from here on...
00124     void InitMenu(ListOfItems &items){
00125         NCursesMenu::InitMenu(items.begin(),is_framed(),FALSE);
00126     }
00127 
00128     /// Put the label text at the left 
00129     /// (0) in the specified row.
00130     virtual void lefttext(int row,const char* label);
00131 
00132     /// Put the label text to the right 
00133     /// (ending at maxx()) in the specified row.
00134     virtual void righttext(int row,const char* label);
00135     
00136     ///Unfortunately, b_framed on parent 
00137     ///is private, so we can't check it...:-(
00138     bool is_framed() const {return have_frame;}
00139     
00140 protected:
00141 
00142     ///Unfortunately, b_framed on parent 
00143     ///is private, so we can't check it...:-(
00144     bool have_frame;
00145     
00146     ///We added a link to this C++ menu object 
00147     ///to our c++ item object.
00148     ///Here we loop through the items linking them to us
00149     void link_items(ListOfItems &items);
00150 };
00151 
00152 
00153 /************************************************************************
00154 *   class NDKMenuBar                                                    *
00155 *   A menu bar is a menu containing popup and regular items             *
00156 *   by default, it has centered top and bottom labels and               *
00157 *   wide orientation                                                    *
00158 ************************************************************************/
00159 class NDKMenuBar : public NDKMenu 
00160 {
00161 protected:
00162     char orientation;
00163     string title;
00164     string bTitle;
00165     string titlePos;
00166     ListOfItems &itemList;
00167     
00168     /// A simple helper
00169     void show_text(const string &t,char where);
00170     
00171 public:
00172     NDKMenuBar (int rows, int cols,int y, int x
00173                     ,ListOfItems &items
00174                     ,const char *ttitle="", const char *btitle=""
00175                     ,const char *title_pos= "cc"
00176                     ,char orient='h',bool framed=false);
00177 
00178     ~NDKMenuBar(){ }    
00179 
00180 
00181     void setTitle(){
00182         show_text(title,titlePos[0]);
00183         show_text(bTitle,titlePos[1]);
00184     }
00185     
00186     ///we are wide-oriented or tall-oriented?
00187     char get_orientation()const{return orientation;}
00188 };
00189 
00190 
00191 /************************************************************************
00192 *   class NDKFramedMenuBar                                              *
00193 *   Ok,don't need to explain what is this, right...?                    *
00194 ************************************************************************/
00195 class NDKFramedMenuBar : public NDKMenuBar
00196 {
00197 public:
00198     NDKFramedMenuBar (int rows, int cols,int y, int x
00199                     ,ListOfItems &items
00200                     ,const char *ttitle="", const char *btitle=""
00201                     ,const char *title_pos= "cc"
00202                     ,char orient='h')
00203         :  NDKMenuBar (rows+2,cols,y,x,items,ttitle,btitle,title_pos
00204                         ,orient,true)
00205     {
00206     }
00207 };
00208 
00209 
00210 /************************************************************************
00211 *   class NDKSubMenu                                                    *
00212 *   A Menu that delpoys itself relative to a popup menu item.           *
00213 ************************************************************************/
00214 class NDKSubMenu : public NDKMenuBar
00215 {
00216 protected:
00217 public:
00218     NDKSubMenu (    int rows, int cols,int y, int x,
00219                     ListOfItems &items,
00220                     const char *ttitle="", const char *btitle="", 
00221                     const char *title_pos= "l", 
00222                     char orient='v',bool framed=true)
00223         :  NDKMenuBar (rows+2, cols+3,y,x,items,ttitle,btitle,title_pos
00224                         ,orient,framed)
00225     {
00226     }
00227     ~NDKSubMenu() { 
00228     }
00229     
00230     void setItems(ListOfItems &items);
00231 };
00232 
00233 
00234 /************************************************************************
00235 *   class NDKPopUpMenu                                                  *
00236 *   A popup menu item which displays a submenu.                         *
00237 *   the popup menu manages the liftime of the items.                    *
00238 ************************************************************************/
00239 class NDKPopUpMenu : public NDKMenuItem
00240 {
00241 public:
00242     NDKPopUpMenu(const char *text=0) : NDKMenuItem(text){   }
00243     ~NDKPopUpMenu();
00244     
00245     bool action();
00246     
00247     ///Autocalculated starting column for the submenu
00248     short submenux() const;
00249     
00250     ///Autocalculated starting row for the submenu
00251     short submenuy()const;
00252         
00253     /// So we can know the right width for the submenu
00254     int largest_name_len()const;
00255 
00256 protected:
00257     ///These are passed to the submenu...
00258     ListOfItems items;
00259 
00260     /// Since submenu is autosized, we can pass
00261     /// longer (i.e. meaningful) labels to it...
00262     string sub_menu_label;
00263 };
00264 
00265 
00266 struct BINDING;
00267 struct BINDING_MAP;
00268 
00269 /************************************************************************
00270 *   class NDKDlgControl                                                 *
00271 *   A Panel which behaves as a basic dialog control.                    *
00272 *   Is the base class for all the dialog controls                       *
00273 ************************************************************************/
00274 class NDKDlgControl : public NCursesPanel
00275 {
00276     friend class NDKDialogBox;
00277 public:
00278     ///The styles a control can have
00279     enum styles{
00280         framed  =   0x0001, ///Do we have a frame?
00281         moveable=   0x0002, ///We can be moved around?
00282         editable=   0x0004, ///Is our text editable?
00283         tabstop =   0x0008, ///Can be looped thru?
00284         notify  =   0x0010, ///Do we notify our parent of events?
00285         hscroll =   0x0020, ///Can we scroll horizontally?
00286         multisel=   0x0040, ///Can select multiple items?
00287         hscrollbar= 0x0100, ///Draw horizontal scrollbar?
00288         vscrollbar= 0x0200  ///Draw vertical scrollbar?
00289     };
00290     
00291     ///The states a control can take
00292     enum states{
00293         unknown =   0x0000,
00294         active  =   0x0001, ///aka Focused
00295         ovrwrt  =   0x0002, ///if editable==true, insert or overwrite?
00296         checked=    0x0004, ///If a selectable control, are we checked?
00297         visible =   0x0008  ///dito
00298     };
00299 
00300     NDKDlgControl(  NDKDlgControl *parent, int id
00301                         ,int lines,int cols,int y, int x,int style=0)
00302         : NCursesPanel(lines,cols,parent->begy()+y,parent->begx()+x)
00303             ,pParent(parent),ctrl_id(id)
00304             ,field_style(style),field_state(unknown)
00305     {
00306         if(has_frame()){
00307             box();
00308         }
00309         set_visible();
00310     }
00311     
00312     NDKDlgControl(int id
00313                         ,int lines,int cols,int y, int x,int style=0)
00314         : NCursesPanel(lines,cols,y,x)
00315             ,pParent(0),ctrl_id(id)
00316             ,field_style(style),field_state(unknown)
00317     {
00318         if(has_frame()){
00319             box();
00320         }
00321         set_visible();
00322     }
00323     ///tell me what styles this window has...
00324     styles get_style() const { return styles(field_style); }
00325      
00326     /// set all styles at once...
00327     styles set_styles(styles s);
00328     
00329     /// set/unset a style bit
00330     styles set_style(styles s,bool on=true);
00331     
00332 
00333     ///tell me what status this window is on...
00334     states get_state() const { return states(field_state); }
00335     
00336     /// set all states at once...
00337     states set_states(states s);
00338     
00339     /// set/unset a state bit
00340     states set_state(states s,bool on=true);
00341     
00342     /// if this style has been set...
00343     bool has_frame()const{return ( (field_style & framed)== framed);}
00344     
00345 
00346     /// the user can move this control?...
00347     bool is_moveable() const{ return ( (field_style & moveable)==moveable);}
00348     
00349     /// the user can edit this control's text?
00350     bool is_editable() const{ return ( (field_style & editable)==editable);}
00351     
00352     /// are we visible on the list viewport?
00353     bool is_visible() const{ return ( (field_state & visible)==visible);}
00354     
00355     /// a control always moves inside its parent boundaries,
00356     /// so make this function use only relative values...
00357     int mvwin(int y, int x);
00358     
00359     
00360     /// Usualy, a control in a dialog has some kind of text on it...
00361     virtual void set_text(const string &txt)=0;
00362     virtual string get_text()const=0 ;
00363     
00364     /// The control identifier
00365     int get_ctrl_id() const {return ctrl_id;};
00366     void set_ctrl_id(int id){ctrl_id=id;};
00367 
00368     /// Maybe these should change to set_focus/unset_focus
00369     virtual void activate();
00370     virtual void deactivate();
00371     
00372     ///show or hide
00373     void set_visible(bool new_state=true){set_state(visible,new_state);}
00374     
00375     ///Ignore /Stop ignoring us when user press tab
00376     void enable(bool t_or_f=true){ set_style(tabstop,t_or_f);}
00377 
00378     /// can make this control the active control?
00379     bool is_enabled()const{ return ( (field_style & tabstop)==tabstop);}
00380     
00381     ///Ignore /Stop ignoring us when user press tab
00382     void set_hscroll(bool t_or_f=true){ set_style(hscroll,t_or_f);}
00383 
00384     /// can make this control the active control?
00385     bool is_hscroll_set()const{ return ( (field_style & hscroll)==hscroll);}
00386 
00387     ///Allow multiple selections
00388     void set_multisel(bool t_or_f=true){ set_style(multisel,t_or_f);}
00389 
00390     /// can make this control the active control?
00391     bool is_multisel()const{ return ( (field_style & multisel)==multisel);}
00392 
00393     ///notify parent of changes
00394     void enable_notify(bool t_or_f=true){ set_style(notify,t_or_f);}
00395 
00396     /// should we notify our parent upon firing of action()?
00397     bool notify_enabled() const{ return ( (field_style & notify)==notify);}
00398     
00399     ///Set edit mode to overwrite or insert
00400     void set_overwrite(bool t_or_f=true){ set_state(ovrwrt,t_or_f);}
00401     
00402     /// the user current pos is overwritten or char is inserted?
00403     bool overwrite()const
00404         { return (is_editable() &&( (field_state & ovrwrt)==ovrwrt));}
00405         
00406 
00407     /// if this style has been set...
00408     bool has_hscrollbar()const{return ( (field_style & hscrollbar)== hscrollbar);}
00409     void set_hscrollbar(bool t_or_f=true){ set_style(hscrollbar,t_or_f);}
00410     
00411     bool has_vscrollbar()const{return ( (field_style & vscrollbar)== vscrollbar);}
00412     void set_vscrollbar(bool t_or_f=true){ set_style(vscrollbar,t_or_f);}
00413                 
00414     void show(){
00415         if(is_visible()) return;
00416         NCursesPanel::show();
00417         set_visible();
00418         enable();
00419     }
00420     
00421     void hide(){
00422         if(!is_visible()) return;
00423         NCursesPanel::hide();
00424         set_visible(false);
00425         enable(false);
00426     }
00427 
00428             
00429     /// Delegation function to get the params from almost anywhere in NDK++
00430     string get_param(const string &section_name
00431                             ,const string &key_name
00432                             ,const string &val);
00433 
00434     /// Delegation function to get the params from almost anywhere in NDK++
00435     long get_param(const string &section_name
00436                             ,const string &key_name
00437                             ,long val);
00438 
00439     /// Delegation function to save the params from almost anywhere in NDK++
00440     string save_param(const string &section_name
00441                             ,const string &key_name
00442                             ,const string &val);
00443 
00444     /// Delegation function to save the params from almost anywhere in NDK++
00445     long save_param(const string &section_name
00446                             ,const string &key_name
00447                             ,long val);
00448     static ofstream &send_to_log(const string &what);
00449 
00450 protected:
00451     NDKDlgControl *pParent;
00452     int ctrl_id;
00453     int field_style;
00454     int field_state;
00455     
00456     ///we won't notify parent if true
00457     bool on_initial_update; 
00458     
00459     /// get a chance at processing the key,
00460     /// before parent does
00461     virtual int driver(int key){ return FALSE;}
00462     
00463 private: 
00464     static const BINDING _bindingEntries[]; 
00465 protected: 
00466     static const BINDING_MAP bindingMap; 
00467     virtual const BINDING_MAP* get_binding_map() const; 
00468 //  static bool resolve_entry(int ctrl_id, int what,void (NDKDlgControl::*)(int)pfn, void* pExtra);
00469     static bool process_message(NDKDlgControl *pTarget
00470                                     , int what, int ctrl_id, void* pExtra);
00471     static const BINDING* get_binding(const BINDING* pEntry
00472                                             ,int what, int ctrl_id);
00473 };
00474 
00475 #include "ndk_bindings.h"
00476 
00477 /************************************************************************
00478 *   class NDKDlgLabel                                                   *
00479 *   A static label à la M$.                                             *
00480 ************************************************************************/
00481 class NDKDlgLabel : public NDKDlgControl
00482 {
00483 public:
00484     NDKDlgLabel( NDKDlgControl *parent,int id,const string &title
00485                     ,int lines,int cols,int y, int x
00486                     ,int style=tabstop|notify);
00487 
00488     NDKDlgLabel( int id,const string &title
00489                     ,int lines,int cols,int y, int x
00490                     ,int style=tabstop|notify);
00491     ~NDKDlgLabel() {}
00492 
00493     void set_text(const string &txt);
00494     string get_text() const {return text;}
00495     
00496     void activate();
00497     void deactivate();
00498 
00499     virtual void clear_text(bool ref=false);
00500     
00501     ///Useful for scrolling labels in lists
00502     chtype operator[](int pos)const
00503     {
00504         chtype result;
00505         
00506         if(pos < 0 || pos >= text.size())
00507             result = getbkgd();
00508         else 
00509             result = text[pos];
00510         
00511         return result;
00512     }
00513     int visible_size() const {return (text.size()-x_start);}
00514 
00515     int max_len() const {return viewport->width();}
00516 protected:
00517     int driver(int key);
00518     
00519     string text;
00520     
00521     ///Hack to manage framed/unframed windows
00522     int pos_x, pos_y;
00523 
00524         
00525     ///Edition viewport.
00526     ///When not framed, viewport = window;
00527     NCursesWindow *viewport;
00528     
00529     ///cursor situation
00530     int cur_x, cur_y;
00531     
00532     /// first visible char
00533     int x_start;
00534 };
00535 
00536 
00537 /************************************************************************
00538 *   class NDKDlgEdit                                                    *
00539 *   A single line, editable control à la M$.                            *
00540 ************************************************************************/
00541 class NDKDlgEdit : public NDKDlgLabel
00542 {
00543 public:
00544     NDKDlgEdit( NDKDlgControl *parent,int id,const string &text
00545                     ,int lines,int cols,int y, int x
00546                     ,int style=framed|editable|tabstop|notify);
00547 
00548     ~NDKDlgEdit();
00549     int edit(int key);
00550     
00551 protected:
00552     virtual int add_or_insert_char(int key);
00553     virtual void add_char(int key);
00554     virtual void insert_char(int key);
00555 
00556     int driver(int key);
00557 };
00558 
00559 
00560 /************************************************************************
00561 *   class NDKDlgButton                                                  *
00562 *   The base class for radio buttons, push buttons and check boxes      *
00563 ************************************************************************/
00564 class NDKDlgButton : public NDKDlgLabel
00565 {
00566 public:
00567     NDKDlgButton( NDKDlgControl *parent,int id, const string &title
00568                     ,int lines,int cols,int y, int x
00569                     ,int style=tabstop|notify);
00570 
00571     void activate();
00572     void deactivate();
00573 
00574     virtual int action()=0;
00575     void set_default(bool t_or_f=true) {default_choice=t_or_f;}
00576     bool is_default()const {return default_choice;}
00577     
00578 protected:
00579     int driver(int key);
00580     bool default_choice;
00581 };
00582 
00583 
00584 /************************************************************************
00585 *   class NDKDlgPushButton                                              *
00586 ************************************************************************/
00587 class NDKDlgPushButton : public NDKDlgButton
00588 {
00589 public:
00590     NDKDlgPushButton( NDKDlgControl *parent,int id, const string &title
00591                     ,int lines,int cols,int y, int x
00592                     ,int style=tabstop|notify|framed);
00593 
00594     NDKDlgPushButton( NDKDlgControl *parent,int id, const string &title
00595                     ,int y, int x);
00596                     
00597     void set_text(const string &txt);
00598 
00599     int action(){ 
00600         process_message(pParent,0,get_ctrl_id(),0);
00601         return TRUE;
00602     }
00603 };
00604 
00605 
00606 /************************************************************************
00607 *   class NDKDlgListItemData                                            *
00608 ************************************************************************/
00609 class NDKDlgListItem; //forward reference
00610 class NDKDlgListItemData
00611 {
00612 public:
00613     NDKDlgListItemData( const string &txt,int id=-1
00614                         ,int style=NDKDlgControl::tabstop|NDKDlgControl::notify
00615                         ,int state=0,void *data=0)
00616         :text(txt),ctrl_id(id),field_style(style)
00617             ,field_state(state),user_data(data)
00618         {
00619         }
00620 
00621     NDKDlgListItemData &operator=(const NDKDlgListItem &lha);
00622     NDKDlgListItemData &operator=(const NDKDlgListItemData &lha);
00623     
00624     void set_text(const string &txt){text = txt;}
00625     string get_text()const  {return text;}
00626 
00627 
00628     void set_ctrl_id(int id)        {ctrl_id = id;}
00629     int get_ctrl_id()   const   {return ctrl_id;}
00630 
00631     void set_styles(int style)  {field_style = style;}
00632     int get_style() const       {return field_style;}
00633 
00634     void set_states(int state)  {field_state = state;}
00635     int get_state() const       {return field_state;}
00636 
00637     /// set/unset a state bit
00638     int set_state(int s,bool on=true);
00639 
00640     void set_user_data(void *data)  {user_data = data;}
00641     void *get_user_data() const     {return user_data;}
00642 
00643     void set_check(bool new_state=true){
00644         bool prev_state=is_checked();
00645         set_state((int)NDKDlgControl::checked,new_state); 
00646     };
00647     
00648     /// is this item selected?
00649     bool is_checked() const 
00650     { return ( (field_state & NDKDlgControl::checked)
00651                     == NDKDlgControl::checked);}
00652 
00653     void set_default(bool t_or_f=true) {default_choice=t_or_f;}
00654     bool is_default()const {return default_choice;}
00655     
00656 protected:
00657     string text;
00658     int ctrl_id;
00659     int field_style;
00660     int field_state;
00661     bool default_choice;
00662     void *user_data;
00663 };
00664 
00665 
00666 /************************************************************************
00667 *   class NDKDlgListItem                                                *
00668 ************************************************************************/
00669 class NDKDlgListItem : public NDKDlgButton
00670 {
00671     friend class NDKDlgListBox;
00672 public:
00673     NDKDlgListItem( NDKDlgControl *parent,int id,const string &title
00674                     ,int lines,int cols,int y, int x,int style=tabstop|notify);
00675 
00676     void set_text(const string &txt);
00677 
00678     ///select/unselect item
00679     void set_check(bool new_state=true){
00680         bool prev_state=is_checked();
00681         set_state(checked,new_state); 
00682         show_state(true);
00683         if(prev_state!=new_state)
00684             process_message(pParent,LI_SEL_CHANGE,get_ctrl_id(),0);
00685     };
00686     
00687     /// is this item selected?
00688     bool is_checked() const { return ( (field_state & checked)==checked);}
00689     
00690     void set_user_data(void *data){user_data = data;}
00691     void *get_user_data() const {return user_data;}
00692     
00693     NDKDlgListItem &operator=(const NDKDlgListItemData &lha);
00694     
00695 protected:
00696     void *user_data;
00697 
00698     int driver(int key);
00699 
00700     ///specialized on children
00701     virtual void show_state(bool ref=false)
00702     {
00703         if(!text.empty()){
00704             if(is_checked()) addch(0,0, '*');
00705             else addch(0,0, ' ');
00706         }
00707         if(ref)refresh();
00708     }
00709     
00710     ///specialized on children
00711     virtual int state_size() const {return 1;};
00712 
00713     ///Hidden from public use
00714     int action() {return FALSE;}
00715 
00716     ///parent notification
00717 //  void notify_change_to_parent()const;
00718 //  void notify_action_to_parent()const;
00719 
00720 };
00721 
00722 
00723 
00724 
00725 /************************************************************************
00726 *   class NDKDlgRadioButton                                             *
00727 ************************************************************************/
00728 class NDKDlgRadioButton : public NDKDlgListItem
00729 {
00730 public:
00731     NDKDlgRadioButton( NDKDlgControl *parent,int id, const string &title
00732                     ,int lines,int cols,int y, int x
00733                     ,int style=tabstop|notify);
00734 
00735     NDKDlgRadioButton( NDKDlgControl *parent,int id, const string &title
00736                     ,int y, int x);
00737 
00738 protected:
00739 
00740     void show_state(bool ref=false){
00741         if(!text.empty()){
00742             if(is_checked()) addstr(0,0, "(0)");
00743             else addstr(0,0, "( )");
00744         }
00745         if(ref)refresh();
00746     }
00747     
00748     int state_size() const {return 3;};
00749 };
00750 
00751 
00752 /************************************************************************
00753 *   class NDKDlgCheckButton                                             *
00754 ************************************************************************/
00755 class NDKDlgCheckButton : public NDKDlgListItem
00756 {
00757 public:
00758     NDKDlgCheckButton( NDKDlgControl *parent,int id, const string &title
00759                     ,int lines,int cols,int y, int x
00760                     ,int style=tabstop|notify);
00761 
00762     NDKDlgCheckButton( NDKDlgControl *parent,int id, const string &title
00763                     ,int y, int x);
00764 
00765 protected:
00766 
00767     void show_state(bool ref=false){
00768         if(!text.empty()){
00769             if(is_checked()) addstr(0,0, "[x]");
00770             else addstr(0,0, "[ ]");
00771         }
00772         if(ref)refresh();
00773     }
00774     
00775     int state_size() const {return 3;};
00776 };
00777 
00778 
00779 
00780 /************************************************************************
00781 *   class NDKDlgListBox                                                 *
00782 *   Base class for managging lists of things                            *
00783 ************************************************************************/
00784 typedef vector<NDKDlgListItem *> VisibleItems;
00785 typedef vector<NDKDlgListItemData *> ListItems;
00786 typedef vector<int> IndexList;
00787 
00788 class NDKDlgListBox : public NDKDlgControl
00789 {
00790     friend class NDKDlgListItem;
00791 public:
00792     NDKDlgListBox( NDKDlgControl *parent,int id,const string &title
00793                     ,int lines,int cols,int y, int x
00794                     ,int style=tabstop|framed|notify);
00795     
00796     ~NDKDlgListBox();
00797     
00798     ///You can add an item just sending in a string
00799     int add_item(const string &new_item, int pos=-1,bool is_default= false,bool make_visible=true);
00800     
00801     /// Here you are sending a full item data ptr.
00802     /// The list will own it and dispose it at destruction time
00803     int add_item(NDKDlgListItemData *new_item,int pos=-1,bool make_visible=true);
00804     
00805     /// Drop an item from the list
00806     int remove_item(int pos=-1);
00807         
00808     ///Here we will manage the virtualized list
00809     int refresh();
00810     
00811     void activate();
00812     void deactivate();
00813     
00814     string get_text() const {return _title;}
00815     void set_text(const string &v){
00816         _title = v;
00817         show_text(v,'l');
00818     }
00819     
00820     virtual int get_cur_pos();
00821     virtual void set_cur_pos(int pos=-1);
00822 
00823     virtual int get_cur_sel();
00824     void set_cur_sel(int pos);
00825     
00826     virtual void get_sel_items(IndexList &list);
00827     virtual void set_sel_items(const IndexList &list, bool t_or_f=true);
00828     
00829     virtual string get_item_text(int pos=-1);
00830     virtual void set_item_text(int pos,const string &txt);
00831         
00832     virtual void *get_item_data(int pos=-1);
00833     virtual void set_item_data(int pos,void *data);
00834 
00835     virtual NDKDlgListItemData *get_item(int pos=-1);
00836     virtual void set_item(int pos,NDKDlgListItemData *item);
00837 
00838     virtual int get_count(){return data.size();};
00839 
00840     void clear();
00841 
00842 protected:
00843     string _title;
00844     int pos_x, pos_y;
00845 
00846     VisibleItems items;
00847     ListItems data;
00848     
00849     int curr_item;
00850     int top_item;
00851     int bottom_item;
00852     int cur_sel;
00853     int driver(int key);
00854 
00855     /// Put the label text at the left (0) 
00856     /// in the specified row.
00857     virtual void lefttext(int row,const char* label);
00858 
00859     /// Put the label text to the right (ending at maxx())
00860     /// in the specified row.
00861     virtual void righttext(int row,const char* label);
00862 
00863     void show_text(const string &t,char where);
00864 
00865     virtual void adjust_top_and_bottom();
00866 
00867     virtual void move_up(); 
00868     virtual void move_down();
00869     virtual void move_left();
00870     virtual void move_right();
00871     
00872     virtual void activate_item(int item_idx);
00873     virtual void deactivate_item(int item_idx);
00874 
00875     void update_data(int item_idx);
00876     void update_item(int item_idx);
00877     
00878     void refresh_items();
00879     void clear_items();
00880     void delete_data();
00881     void show_empty();
00882     
00883     void draw_scrollbar();
00884     NDKDlgListItem *&visible_item(int requested)
00885                                     {return items[requested-top_item];}
00886 
00887     void check_multisel(int pos, bool t_or_f);
00888     
00889     void on_sel_change(int);
00890     
00891     DECLARE_BINDINGS();
00892 };
00893 
00894 
00895 /************************************************************************
00896 *   class NDKDlgSelectionBox                                            *
00897 *                                                                       *
00898 ************************************************************************/
00899 class NDKDlgSelectionBox : public NDKDlgListBox
00900 {
00901 public:
00902     NDKDlgSelectionBox( NDKDlgControl *parent,int id,const string &title
00903                     ,int lines,int cols,int y, int x
00904                     ,int style=tabstop|framed|notify)
00905         :NDKDlgListBox( parent,id,title
00906                     ,lines,cols,y, x
00907                     ,style)
00908         {
00909             initialize_items();
00910         }
00911                     
00912 protected:
00913     void initialize_items();
00914 };
00915 
00916 
00917 /************************************************************************
00918 *   class NDKDlgCheckListBox                                            *
00919 *                                                                       *
00920 ************************************************************************/
00921 class NDKDlgCheckListBox : public NDKDlgListBox
00922 {
00923 public:
00924     NDKDlgCheckListBox( NDKDlgControl *parent,int id,const string &title
00925                     ,int lines,int cols,int y, int x
00926                     ,int style=tabstop|framed|notify)
00927         :NDKDlgListBox( parent,id,title
00928                     ,lines,cols,y, x
00929                     ,style)
00930         {
00931             initialize_items();
00932         }
00933                     
00934 protected:
00935     void initialize_items();
00936 };
00937 
00938 
00939 /************************************************************************
00940 *   class NDKDlgChoiceBox                                               *
00941 *                                                                       *
00942 ************************************************************************/
00943 class NDKDlgChoiceBox : public NDKDlgListBox
00944 {
00945 public:
00946     NDKDlgChoiceBox( NDKDlgControl *parent,int id,const string &title
00947                     ,int lines,int cols,int y, int x
00948                     ,int style=tabstop|framed|notify)
00949         :NDKDlgListBox( parent,id,title
00950                     ,lines,cols,y, x
00951                     ,style)
00952         {
00953             initialize_items();
00954         }
00955                     
00956 protected:
00957     void initialize_items();
00958 };
00959 
00960 
00961 /************************************************************************
00962 *   class NDKDialogBox                                                  *
00963 *   A dialog box made up from a framed pad and a panel.                 *
00964 ************************************************************************/
00965 typedef vector <NDKDlgControl *> ListOfChildren;
00966 
00967 class NDKDialogBox: public NDKDlgControl
00968 {
00969 public:
00970     enum dlg_styles{
00971         info        = 0x0100,
00972         warning     = 0x0200,
00973         error       = 0x0400,
00974         okCancel    = 0x0001,
00975         yesNo       = 0x0002,
00976         yesNoCancel = 0x0004
00977     };
00978 
00979     enum Dlg_Request{
00980         DLG_LOW = PAD_HIGH + 1,
00981         REQ_DLG_REFRESH = DLG_LOW,
00982         REQ_DLG_PROCESSED,
00983         REQ_DLG_NEXT,
00984         REQ_DLG_PREV,
00985         REQ_DLG_UP,
00986         REQ_DLG_DOWN,
00987         REQ_DLG_LEFT,
00988         REQ_DLG_RIGHT,
00989         REQ_DLG_EXIT,
00990         DLG_HIGH = REQ_DLG_EXIT
00991     };
00992 
00993     NDKDialogBox(int id, const string &title
00994                         ,int lines, int cols,int y=0, int x=0
00995                         ,int style=0);
00996     ~NDKDialogBox();
00997     
00998     void add_child(NDKDlgControl *new_child){ 
00999             children.push_back(new_child);
01000     }   
01001     
01002     string get_text() const {return _title;}
01003     void set_text(const string &v){
01004         _title = v;
01005         show_text(v,'c');
01006     }
01007 
01008     int do_modal();
01009 
01010     static NCursesPanel dlg_stdscr;
01011     
01012 protected:
01013     ///Allow children to touch our stuff
01014     friend NDKDlgControl;
01015     /// The controls we have
01016     ListOfChildren children;
01017     
01018     /// where is te focus now
01019     int curr_child;
01020     
01021     string _title;
01022     
01023     int dlg_style;
01024     
01025     ///Modal loop condition
01026     bool bContinueModal;
01027     
01028     ///So we can ask the user if she want to save
01029     bool changed;
01030     
01031     NDKDlgPushButton *pBtnYes;
01032     NDKDlgPushButton *pBtnNo;
01033     NDKDlgPushButton *pBtnCancel;
01034     NDKDlgPushButton *pBtnOk;
01035 
01036     ///this is the result of the interaction
01037     int user_request;
01038     
01039     /// A simple helper
01040     void show_text(const string &t,char where);
01041 
01042     /// When user press TAB, give me the next child
01043     void next_control();
01044 
01045 protected:
01046     DECLARE_BINDINGS();
01047 
01048     ///called at the beggining of the modal loop
01049     virtual void on_dlg_init(){}
01050         
01051     ///called at the end of the modal loop
01052     virtual void on_dlg_term(){ }
01053     
01054     ///called if user presses one of the 'exits' 
01055     virtual bool can_close();
01056     
01057     ///called when the user enters a control
01058     virtual void on_ctrl_init(NDKDlgControl &ctrl){
01059         ctrl.activate();
01060     }
01061     
01062     ///called when the user leaves the control
01063     virtual void on_ctrl_term(NDKDlgControl &ctrl){
01064         ctrl.deactivate();
01065     }
01066     
01067     /// Kind of catch-all for derived windows
01068     virtual void on_cmd(int dlg_req) {
01069     }
01070     
01071     ///called on construction of dialog
01072     virtual void create_buttons();
01073     
01074     ///The next four are used by create_buttons
01075     void add_ok();
01076     void add_ok_cancel();
01077     void add_yes_no(); 
01078     void add_yes_no_cancel(); 
01079 
01080     ///activate child at position child_idx
01081     virtual void set_focus_to(int child_idx);
01082 
01083     ///activate p_child
01084     virtual void set_focus_to(NDKDlgControl *p_child);
01085 
01086     int driver (int key);
01087     
01088     ///Vanilla implementation of exits
01089     virtual void on_dlg_ok()    {end_dialog(IDOK);} 
01090     virtual void on_dlg_yes()   {end_dialog(IDYES);}
01091     virtual void on_dlg_no()    {end_dialog(IDNO);}
01092     virtual void on_dlg_cancel(){
01093         if(can_close())
01094             end_dialog(IDCANCEL);
01095     }
01096 
01097     ///Break the modal loop
01098     ///and give the user a chance to cleanup/serialize/whatever
01099     int end_dialog(int request){
01100         user_request = request;
01101         bContinueModal=false;
01102         on_dlg_term();
01103     }
01104 
01105     /// Put the label text at the left (0) 
01106     /// in the specified row.
01107     virtual void lefttext(int row,const char* label);
01108 
01109     /// Put the label text to the right (ending at maxx())
01110     /// in the specified row.
01111     virtual void righttext(int row,const char* label);
01112     static int my_w;        ///useable width
01113     static int btn_w;       ///each button width
01114     static int btns;            ///number of buttons
01115     static int used_width;  ///total buttons width          
01116     static int spc;         ///space between buttons
01117     static int X_POS(int pos);
01118 
01119     static string lblOk;
01120     static string lblCancel;
01121     static string lblYes;   
01122     static string lblNo;
01123     static string titDataChgd;
01124     static string msgAskToSave;
01125 };
01126 
01127 
01128 /************************************************************************
01129 *   class NDKMessageBox                                                 *
01130 *   You already know what is this... ;-)                                *
01131 ************************************************************************/
01132 class NDKMessageBox: public NDKDialogBox 
01133 {
01134 public:
01135     NDKMessageBox(const string &title,const string &message,int style=info);
01136 protected:
01137 
01138     ///Prompt the user
01139     string msg;
01140 
01141     ///We redefine here so we get called on construction
01142     void on_dlg_init(); 
01143     void show_message();
01144 };
01145 
01146 typedef NDKMessageBox  MessageBox;
01147 
01148 
01149 /************************************************************************
01150 *   class NDKOkCancelBox                                                    *
01151 *   You already know what is this... ;-)                                *
01152 ************************************************************************/
01153 class NDKOkCancelBox: public NDKMessageBox 
01154 {
01155 public:
01156     NDKOkCancelBox(const string &title,const string &message,int style=info)
01157         :NDKMessageBox(title,message,style|okCancel)
01158         {};
01159 };
01160 
01161 typedef NDKOkCancelBox  OkCancelBox;
01162 
01163 
01164 /************************************************************************
01165 *   class NDKYesNoBox                                                   *
01166 *   You already know what is this... ;-)                                *
01167 ************************************************************************/
01168 class NDKYesNoBox: public NDKMessageBox 
01169 {
01170 public:
01171     NDKYesNoBox(const string &title,const string &message,int style=info)
01172         :NDKMessageBox(title,message,style|yesNo)
01173         {};
01174 };
01175 
01176 typedef NDKYesNoBox  YesNoBox;
01177 
01178 
01179 /************************************************************************
01180 *   class NDKYesNoBox                                                   *
01181 *   You already know what is this... ;-)                                *
01182 ************************************************************************/
01183 class NDKYesNoCancelBox: public NDKMessageBox 
01184 {
01185 public:
01186     NDKYesNoCancelBox(const string &title,const string &message,int style=info)
01187         :NDKMessageBox(title,message,style|yesNoCancel)
01188         {};
01189 };
01190 typedef NDKYesNoCancelBox  YesNoCancelBox;
01191 
01192 
01193 /************************************************************************
01194 *   class NDKStatusBar                                                  *
01195 *   No need to explain this, right...? :-)                              *
01196 ************************************************************************/
01197 class NDKStatusBar : public NDKDlgLabel
01198 {
01199 public:
01200 
01201     NDKStatusBar(int lines,int cols,int y, int x,const string &text="Status bar")
01202         : NDKDlgLabel(1000,text
01203                         ,lines, cols, y, x, visible)
01204     {
01205     }
01206 };
01207 
01208 
01209 /************************************************************************
01210 *   class NDKApplication                                                *
01211 *   Derivation of the NCursesApplication class                          *
01212 *   where we added a status bar                                         *
01213 ************************************************************************/
01214 class NDKApplication: public NCursesApplication
01215 {
01216 protected:
01217 
01218     NDKApplication(bool wantColors = FALSE)
01219         :   NCursesApplication(wantColors),pStatusBar(0)
01220     {
01221     }
01222     
01223     virtual void activateMenuBar(ListOfItems &items)=0;
01224     virtual void activateStatusBar();
01225   
01226 public:
01227 
01228     static NDKApplication *get_application(){
01229         NDKApplication *pApp = dynamic_cast<NDKApplication *>
01230                                         (NCursesApplication::getApplication());
01231         return pApp;
01232     }
01233     
01234     virtual ~NDKApplication(){
01235         delete pStatusBar;
01236     };
01237 
01238     NDKStatusBar *getStatusBar() {return pStatusBar;}
01239 
01240     ///Tell us what is the name of the parameters file  
01241     void set_param_file_name(const string &file_name){param_file_name = file_name;}
01242     
01243     /// Retrive the parameters file name
01244     string get_param_file_name()const {return param_file_name;}
01245     
01246     /// Find a string parameter (a la MS's .ini files)
01247     string get_param(const string &section_name
01248                         ,const string &key_name
01249                         ,const string &val);
01250 
01251     /// Find a numeric parameter (a la MS's .ini files)
01252     long get_param(const string &section_name
01253                         ,const string &key_name
01254                         ,long val);
01255 
01256     /// Save a string parameter (a la MS's .ini files)
01257     string save_param(const string &section_name
01258                         ,const string &key_name
01259                         ,const string &val){};
01260 
01261     /// Save a numeric parameter (a la MS's .ini files)
01262     long save_param(const string &section_name
01263                         ,const string &key_name
01264                         ,long val){};
01265 
01266 protected:
01267 
01268     NDKStatusBar *pStatusBar;
01269     string param_file_name;
01270     
01271     ///Helper to check if a section given in ge/save_param functs. exists
01272     bool section_exists(ifstream &param_file,const string &section_name);
01273     
01274     ///Helper to check if a key given in ge/save_param functs. exists
01275     long find_key(ifstream &param_file,const string &section_name
01276                             ,const string &key_name,string &value);
01277 
01278 };
01279 
01280 
01281 /// Delegation function to get the params from almost anywhere in NDK++
01282 inline long NDKDlgControl::get_param(const string &section_name
01283                                     ,const string &key_name
01284                                     ,long val)
01285 {
01286     return  NDKApplication::get_application()->get_param(section_name,key_name,val);
01287 }
01288 
01289 
01290 /// Delegation function to get the params from almost anywhere in NDK++
01291 inline string NDKDlgControl::get_param(const string &section_name
01292                                     ,const string &key_name
01293                                     ,const string &val)
01294 {
01295     return  NDKApplication::get_application()->get_param(section_name,key_name,val);
01296 }
01297 
01298 
01299 /// Delegation function to set the params from almost anywhere in NDK++
01300 inline long NDKDlgControl::save_param(const string &section_name
01301                                     ,const string &key_name
01302                                     ,long val)
01303 {
01304     return  NDKApplication::get_application()->save_param(section_name,key_name,val);
01305 }
01306 
01307 
01308 /// Delegation function to set the params from almost anywhere in NDK++
01309 inline string NDKDlgControl::save_param(const string &section_name
01310                                     ,const string &key_name
01311                                     ,const string &val)
01312 {
01313     return  NDKApplication::get_application()->save_param(section_name,key_name,val);
01314 }
01315 
01316 /************************************************************************
01317 *   class ClosingMarkItem                                               *
01318 *   The end marker for an items list.                                   *
01319 ************************************************************************/
01320 class ClosingMarkItem : public NDKMenuItem
01321 {
01322 protected:
01323 public:
01324   ClosingMarkItem() : NDKMenuItem() { }
01325   ~ClosingMarkItem(){ 
01326   }
01327 };
01328 
01329 
01330 /************************************************************************
01331 *   class NonImplementedItem                                            *
01332 *   A non-functional item (you can draft your menu with these.          *
01333 ************************************************************************/
01334 class NonImplementedItem : public NDKMenuItem {
01335 public:
01336     NonImplementedItem(const char *text) : NDKMenuItem(text) {
01337         options_off(O_SELECTABLE);
01338     }
01339     ~NonImplementedItem(){
01340     }
01341 };
01342 
01343 
01344 /************************************************************************
01345 *   class ExitCmd                                                       *
01346 *   This is the one to take us off the menu.                            *
01347 ************************************************************************/
01348 class ExitCmd : public NDKMenuItem
01349 {
01350 public:
01351   ExitCmd(const char *text="Exit") : NDKMenuItem(text) { }
01352   ~ExitCmd(){}
01353   bool action() { return TRUE; }
01354 };
01355 
01356 
01357 /************************************************************************
01358 *   class BackCmd                                                       *
01359 *   Useful if you don't have a mouse.                                   *
01360 *   Put it first on your drop down menu so you are                      *
01361 *   just an enter away from the menu bar                                *
01362 ************************************************************************/
01363 class BackCmd : public NDKMenuItem
01364 {
01365 public:
01366   BackCmd(const char *text="Back") : NDKMenuItem(text) { }
01367   ~BackCmd(){}
01368   bool action() { return TRUE; }
01369 };
01370 
01371 
01372 
01373 /************************************************************************
01374 *   template class NDKDlgException                                      *
01375 *   We use it from anywhere in NDK++ to throw using the                 *
01376 *   current context (usually the window containing the offending code)  *
01377 ************************************************************************/
01378 template<class T> class NDKDlgException : public NCursesException
01379 {
01380 public:
01381   const T* pElem;
01382 
01383   NDKDlgException (const char *msg, int err) : 
01384     NCursesException (msg, err),
01385     pElem (0)
01386     {};
01387 
01388   NDKDlgException (const T* elem,
01389              const string &msg,
01390              int err=-1) : 
01391     NCursesException (msg.c_str(), err),
01392     pElem (elem)
01393     {};
01394 
01395   NDKDlgException (int err) : 
01396     NCursesException ("NDK++ library exception", err),
01397     pElem (0)
01398     {};
01399 
01400   NDKDlgException (const T* elem,
01401              int err) : 
01402     NCursesException ("NDK++ library exception", err),
01403     pElem (elem)
01404     {};
01405 
01406   virtual const char *classname() const {
01407     return typeid(pElem).name();
01408   }
01409 
01410 };
01411 
01412 
01413 
01414 } //namespace NDK_XX
01415 
01416 
01417 
01418 
01419 #endif //!defined(__NDK_NCURSES__)

Generated on Tue Aug 27 10:49:45 2002 by doxygen1.2.17