MechSys  1.0
Computing library for simulations in continuum and discrete mechanics
/home/dorival/mechsys/lib/gui/common.h
Go to the documentation of this file.
00001 /************************************************************************
00002  * MechSys - Open Library for Mechanical Systems                        *
00003  * Copyright (C) 2005 Dorival M. Pedroso, Raul Durand                   *
00004  * Copyright (C) 2009 Sergio Galindo                                    *
00005  *                                                                      *
00006  * This program is free software: you can redistribute it and/or modify *
00007  * it under the terms of the GNU General Public License as published by *
00008  * the Free Software Foundation, either version 3 of the License, or    *
00009  * any later version.                                                   *
00010  *                                                                      *
00011  * This program is distributed in the hope that it will be useful,      *
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the         *
00014  * GNU General Public License for more details.                         *
00015  *                                                                      *
00016  * You should have received a copy of the GNU General Public License    *
00017  * along with this program. If not, see <http://www.gnu.org/licenses/>  *
00018  ************************************************************************/
00019 
00020 #ifndef MECHSYS_GUI_COMMON_H
00021 #define MECHSYS_GUI_COMMON_H
00022 
00023 // STL
00024 #include <map>
00025 #include <sstream>
00026 #include <cstring> // for strcmp
00027 
00028 // FLTK or wxWidgets
00029 #if defined(USE_FLTK)
00030   #include <FL/Enumerations.H>
00031   #include <FL/fl_draw.H>
00032 #elif defined(USE_WXWIDGETS)
00033   #include <wx/pen.h>
00034   #include <wx/font.h>
00035   #include <wx/gdicmn.h>
00036   #include <wx/dcbuffer.h>
00037   #include <wx/valgen.h>
00038   #include <wx/scrolwin.h>
00039   #include <wx/checkbox.h>
00040   #include <wx/combobox.h>
00041   #include <wx/textctrl.h>
00042   #include <wx/filedlg.h>
00043   #include <wx/sizer.h>
00044   #include <wx/button.h>
00045   #include <wx/stattext.h>
00046   #include <wx/menu.h>
00047   #include <wx/aui/aui.h>
00048   #include <wx/msgdlg.h>
00049   #include <wx/log.h>
00050   #include <wx/thread.h>
00051   #include <mechsys/gui/wxnuminput.h>
00052   #include <mechsys/gui/wxstringvalidator.h>
00053 #else
00054   #error MechSys:gui/common.h: Either USE_FLTK or USE_WXWIDGETS must be defined
00055 #endif
00056 
00057 // MechSys
00058 #include <mechsys/util/string.h>
00059 #include <mechsys/util/fatal.h>
00060 #include <mechsys/util/array.h>
00061 
00062 #ifdef USE_WXWIDGETS
00063 
00064     void WxError (String const & Fmt, ...)
00065     {
00066         String msg;
00067         va_list       arg_list;
00068         va_start     (arg_list, Fmt);
00069         msg.PrintfV  (Fmt, arg_list);
00070         va_end       (arg_list);
00071         wxMessageBox (msg, "Error", wxOK|wxICON_ERROR);
00072     }
00073 
00074   #define SHOW_ALL_WXPANES(AUI)                           \
00075     for (size_t i=0; i<AUI.GetAllPanes().GetCount(); ++i) \
00076     {                                                     \
00077         AUI.GetAllPanes().Item(i).Show(true);             \
00078         AUI.GetAllPanes().Item(i).Dock();                 \
00079     }                                                     \
00080     AUI.Update();
00081  
00082   #define WXMSG(MSG) wxMessageBox(MSG,"Message",wxOK|wxICON_INFORMATION);
00083   #define WXMSGINT(VAL) { wxString buf; buf.Printf("%d",VAL); WXMSG(buf); }
00084   #define WXMSGVAL(VAL) { wxString buf; buf.Printf("%g",VAL); WXMSG(buf); }
00085 
00086   #define ADD_WXMENUSTATUS(MNU, MNU_FILE, MNU_WND, MNU_RUN, MNU_HELP) \
00087     wxMenuBar * MNU     = new wxMenuBar; \
00088     wxMenu    * MNU_FLE = new wxMenu;    \
00089     wxMenu    * MNU_WND = new wxMenu;    \
00090     wxMenu    * MNU_RUN = new wxMenu;    \
00091     wxMenu    * MNU_HLP = new wxMenu;    \
00092     MNU_FLE -> Append (wxID_EXIT      , "&Quit\tCtrl-Q" , "Quit this program"); \
00093     MNU_WND -> Append (ID_MNU_SHOWALL , "&Show All"     , "Show all windows" ); \
00094     MNU_RUN -> Append (ID_MNU_RUN     , "&Run\tCtrl-R"  , "Run simulation"   ); \
00095     MNU_HLP -> Append (wxID_ABOUT     , "&About\tF1"    , "Show about dialog"); \
00096     MNU     -> Append (MNU_FLE        , "&File"         ); \
00097     MNU     -> Append (MNU_WND        , "&Window"       ); \
00098     MNU     -> Append (MNU_RUN        , "&Run"          ); \
00099     MNU     -> Append (MNU_HLP        , "&Help"         ); \
00100     SetMenuBar      (mnu);       \
00101     CreateStatusBar (2);         \
00102     SetStatusText   ("Welcome");
00103 
00104   #define ADD_WXTOOLBAR(TBR) \
00105     wxAuiToolBar * TBR = new wxAuiToolBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_OVERFLOW); \
00106     TBR->AddTool (ID_TBR_RUN,  "Run",  gear_sml_xpm); \
00107     TBR->AddTool (ID_TBR_STOP, "Stop", stop_xpm);     \
00108     TBR->SetToolBitmapSize (wxSize(16,16));           \
00109     TBR->Realize();
00110 
00111   #define ADD_LOGPANEL(LOG) \
00112     Log = new wxTextCtrl (this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxNO_BORDER | wxTE_MULTILINE | wxTE_READONLY); \
00113     wxLog::SetActiveTarget (new wxLogTextCtrl(Log));
00114 
00115   #define ADD_WXPANEL(PNL, SZTOP, SZR, M, N)                                \
00116     wxScrolled<wxPanel> * PNL   = new wxScrolled<wxPanel> (this, wxID_ANY); \
00117     wxBoxSizer          * SZTOP = new wxBoxSizer (wxVERTICAL);              \
00118     wxFlexGridSizer     * SZR   = new wxFlexGridSizer (M,N,0,0);            \
00119     PNL->SetSizer (SZTOP);                                                  \
00120     PNL->SetScrollbars(10,10,0,0);                                          \
00121     PNL->GetSizer()->Add (SZR,0,wxALIGN_LEFT|wxALL|wxEXPAND);               \
00122     PNL->GetSizer()->Fit (PNL);                                             \
00123     PNL->GetSizer()->SetSizeHints (PNL);
00124 
00125   #define ADD_WXNOTEBOOK(WND, NBK) \
00126     wxAuiNotebook * NBK = new wxAuiNotebook(WND, wxID_ANY, wxDefaultPosition, wxDefaultSize, (wxAUI_NB_DEFAULT_STYLE | wxAUI_NB_TAB_EXTERNAL_MOVE | wxNO_BORDER | wxAUI_NB_WINDOWLIST_BUTTON) & ~(wxAUI_NB_CLOSE_BUTTON | wxAUI_NB_CLOSE_ON_ACTIVE_TAB | wxAUI_NB_CLOSE_ON_ALL_TABS));
00127 
00128   #define ADD_WXNOTEBOOK_(WND, NBK) \
00129     NBK = new wxAuiNotebook(WND, wxID_ANY, wxDefaultPosition, wxDefaultSize, (wxAUI_NB_DEFAULT_STYLE | wxAUI_NB_TAB_EXTERNAL_MOVE | wxNO_BORDER | wxAUI_NB_WINDOWLIST_BUTTON) & ~(wxAUI_NB_CLOSE_BUTTON | wxAUI_NB_CLOSE_ON_ACTIVE_TAB | wxAUI_NB_CLOSE_ON_ALL_TABS));
00130 
00131   #define ADD_WXBUTTON(PNL, SZR, ID, CTRL, LBL) \
00132     wxButton * CTRL = new wxButton (PNL, ID, LBL, wxDefaultPosition, wxDefaultSize, 0); \
00133     SZR->Add (CTRL, 0,wxALIGN_LEFT|wxALL|wxEXPAND,2);
00134 
00135   #define ADD_WXCHECKBOX(PNL, SZR, ID, CTRL, LBL, VAR) \
00136     wxCheckBox * CTRL = new wxCheckBox (PNL, ID, LBL, wxDefaultPosition, wxDefaultSize, 0, wxGenericValidator(&VAR)); \
00137     CTRL->SetValue (VAR); \
00138     SZR->Add (CTRL, 0,wxALIGN_LEFT|wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL,2);
00139 
00140   #define ADD_WXCHECKBOX2(PNL, SZR, ID, CTRL, LBL, VAR) \
00141     wxCheckBox * CTRL = new wxCheckBox (PNL, ID, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, wxGenericValidator(&VAR)); \
00142     CTRL->SetValue (VAR); \
00143     SZR->Add (new wxStaticText(PNL,wxID_ANY,LBL), 0,wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL,2); \
00144     SZR->Add (CTRL, 0,wxALIGN_LEFT|wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL,2);
00145 
00146   #define ADD_WXCOMBOBOX(PNL, SZR, ID, CTRL, LBL) \
00147     CTRL = new wxComboBox (PNL, ID, LBL, wxDefaultPosition, wxDefaultSize, 0); \
00148     SZR->Add (CTRL, 0,wxALIGN_LEFT|wxALL|wxEXPAND,2);
00149 
00150   #define ADD_WXTEXTCTRL(PNL, SZR, ID, CTRL, LBL, VAR) \
00151     wxTextCtrl * CTRL = new wxTextCtrl (PNL, ID, VAR, wxDefaultPosition, wxDefaultSize, 0, WxStringValidator(&VAR)); \
00152     SZR->Add (CTRL, 0,wxALIGN_LEFT|wxALL|wxEXPAND,2);
00153 
00154   #define ADD_WXTEXTCTRL_(PNL, SZR, ID, CTRL, LBL, VAR) \
00155     CTRL = new wxTextCtrl (PNL, ID, VAR, wxDefaultPosition, wxDefaultSize, 0, WxStringValidator(&VAR)); \
00156     SZR->Add (CTRL, 0,wxALIGN_LEFT|wxALL|wxEXPAND,2);
00157 
00158   #define ADD_WXTEXTCTRL2(PNL, SZR, ID, CTRL, LBL, VAR) \
00159     wxTextCtrl * CTRL = new wxTextCtrl (PNL, ID, VAR, wxDefaultPosition, wxDefaultSize, 0, WxStringValidator(&VAR)); \
00160     SZR->Add (new wxStaticText(PNL,wxID_ANY,LBL), 0,wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL,2); \
00161     SZR->Add (CTRL, 0,wxALIGN_LEFT|wxALL|wxEXPAND,2);
00162 
00163   #define ADD_WXNUMINPUT(PNL, SZR, ID, CTRL, LBL, VAR) \
00164     WxNumInput * CTRL = new WxNumInput (PNL, ID, VAR, wxDefaultPosition, wxDefaultSize, 0, WxNumValidator(&VAR)); \
00165     SZR->Add (CTRL, 0,wxALIGN_LEFT|wxALL|wxEXPAND,2);
00166 
00167   #define ADD_WXNUMINPUT2(PNL, SZR, ID, CTRL, LBL, VAR) \
00168     WxNumInput * CTRL = new WxNumInput (PNL, ID, VAR, wxDefaultPosition, wxDefaultSize, 0, WxNumValidator(&VAR)); \
00169     SZR->Add (new wxStaticText(PNL,wxID_ANY,LBL), 0,wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL,2); \
00170     SZR->Add (CTRL, 0,wxALIGN_LEFT|wxALL|wxEXPAND,2);
00171 
00172   #define DECLARE_THREAD(THNAME, FRAMENAME)           \
00173     class THNAME : public wxThread                    \
00174     {                                                 \
00175       public:                                         \
00176         THNAME(FRAMENAME * F) : wxThread(), Fra(F) {} \
00177         wxThread::ExitCode Entry();                   \
00178         FRAMENAME * Fra;                              \
00179     };
00180 
00181   #define SPAWN_THREAD(THNAME, TH, ISRUNNING)                                        \
00182     if (ISRUNNING) throw new Fatal("Simulation is running");                         \
00183     THNAME * TH = new THNAME(this);                                                  \
00184     if (TH->Create()!=wxTHREAD_NO_ERROR) throw new Fatal("Could not create thread"); \
00185     TH->SetPriority (WXTHREAD_MAX_PRIORITY);                                         \
00186     if (TH->Run()!=wxTHREAD_NO_ERROR) throw new Fatal("Could not start thread");     \
00187     ISRUNNING = true;
00188 
00189   #define WXCATCH(WITH_ERROR, ERROR_MSG)                                          \
00190     catch (Fatal      * e)     { WITH_ERROR=true; ERROR_MSG=e->Msg(); delete e; } \
00191     catch (char const * m)     { WITH_ERROR=true; ERROR_MSG=m; }                  \
00192     catch (std::exception & e) { WITH_ERROR=true; ERROR_MSG=e.what(); }           \
00193     catch (...)                { WITH_ERROR=true; ERROR_MSG="Some exception (...) occurred"; }
00194 
00195 #endif
00196 
00197 namespace GUI
00198 {
00199 
00200 
00202 
00203 
00204 #if defined(USE_FLTK)
00205 class DeviceContext
00206 #elif defined(USE_WXWIDGETS)
00207 class DeviceContext : public wxBufferedPaintDC
00208 #endif
00209 {};
00210 
00211 
00213 
00214 
00215 #if defined(USE_FLTK)
00216 typedef std::map<String,Fl_Color> Colours_t;
00217 #elif defined(USE_WXWIDGETS)
00218 typedef std::map<String,wxColour> Colours_t;
00219 #endif
00220 
00221 #if defined(USE_WXWIDGETS)
00222 wxColourDatabase ClrDb;
00223 #endif
00224 
00225 class Colours : public Colours_t
00226 {
00227 public:
00228     // Constructor
00229     Colours()
00230     {
00231         // basic colours
00232 #if defined(USE_FLTK)
00233         (*this)["black"]   = FL_BLACK;
00234         (*this)["blue"]    = FL_BLUE;
00235         (*this)["cyan"]    = FL_CYAN;
00236         (*this)["green"]   = FL_GREEN;
00237         (*this)["magenta"] = FL_MAGENTA;
00238         (*this)["red"]     = FL_RED;
00239         (*this)["white"]   = FL_WHITE;
00240         (*this)["yellow"]  = FL_YELLOW;
00241 #elif defined(USE_WXWIDGETS)
00242         if (ClrDb.Find("BLACK")  .Ok()) (*this)["black"]   = ClrDb.Find("BLACK");
00243         if (ClrDb.Find("BLUE")   .Ok()) (*this)["blue"]    = ClrDb.Find("BLUE");
00244         if (ClrDb.Find("CYAN")   .Ok()) (*this)["cyan"]    = ClrDb.Find("CYAN");
00245         if (ClrDb.Find("GREEN")  .Ok()) (*this)["green"]   = ClrDb.Find("GREEN");
00246         if (ClrDb.Find("MAGENTA").Ok()) (*this)["magenta"] = ClrDb.Find("MAGENTA");
00247         if (ClrDb.Find("RED")    .Ok()) (*this)["red"]     = ClrDb.Find("RED");
00248         if (ClrDb.Find("WHITE")  .Ok()) (*this)["white"]   = ClrDb.Find("WHITE");
00249         if (ClrDb.Find("YELLOW") .Ok()) (*this)["yellow"]  = ClrDb.Find("YELLOW");
00250 #endif
00251         // additional colours
00252         (*this)["pink"]    = (*this)(250, 204, 228);
00253         (*this)["lblue"]   = (*this)(217, 228, 255);
00254         (*this)["lgreen"]  = (*this)(100, 241, 193);
00255         (*this)["dblue"]   = (*this)( 45,   0, 160);
00256         (*this)["orange"]  = (*this)(241, 125,   0);
00257         (*this)["lyellow"] = (*this)(234, 228, 179);
00258         (*this)["dgreen"]  = (*this)(  0, 111,   5);
00259     }
00260 
00261     // Operators
00262 #if defined(USE_FLTK)
00263     Fl_Color operator() (char const * Name)
00264 #elif defined(USE_WXWIDGETS)
00265     wxColour operator() (char const * Name)
00266 #endif
00267     {
00268         if (Name==NULL) throw new Fatal("GUI::Colours(): Name must not be NULL");
00269         Colours_t::const_iterator p = this->find(Name);
00270         if (p==this->end()) throw new Fatal("GUI::Colours(): Colour '%s' is not available",Name);
00271         return p->second;
00272     }
00273 
00274 #if defined(USE_FLTK)
00275     Fl_Color operator() (unsigned char R, unsigned char G, unsigned char B, char const * Name=NULL)
00276     {
00277         if (Name==NULL) return fl_rgb_color (R,G,B);
00278         else
00279         {
00280             Colours_t::const_iterator p = this->find(Name);
00281             if (p==this->end()) // add new
00282             {
00283                 Fl_Color clr = fl_rgb_color (R,G,B);
00284                 (*this)[Name] = clr;
00285                 return clr;
00286             }
00287             else return p->second;
00288         }
00289     }
00290 #elif defined(USE_WXWIDGETS)
00291     wxColour operator() (unsigned char R, unsigned char G, unsigned char B, char const * Name=NULL)
00292     {
00293         if (Name==NULL) return wxColour(R,G,B);
00294         else
00295         {
00296             Colours_t::const_iterator p = this->find(Name);
00297             if (p==this->end()) // add new
00298             {
00299                 wxColour clr(R,G,B);
00300                 (*this)[Name] = clr;
00301                 return clr;
00302             }
00303             else return p->second;
00304         }
00305     }
00306 #endif
00307 
00308 };
00309 
00310 // Allocate colours
00311 Colours Clr;
00312 
00313 // Line colors
00314 Array<String> __lin_clr;
00315 int __init_lin_clr ()
00316 {
00317     __lin_clr.Resize (10);
00318     __lin_clr = "red", "blue", "dgreen", "magenta", "dblue", "green", "orange", "cyan", "pink", "yellow";
00319     return 0;
00320 }
00321 int __dummy_init_lin_clr = __init_lin_clr();
00322 
00323 inline char const * LinClr (int Idx=0) { return __lin_clr[Idx % __lin_clr.Size()].CStr(); }
00324 
00325 
00327 
00328 
00329 typedef std::map<String,int> LineTypes_t;
00330 
00331 class LineTypes : public LineTypes_t
00332 {
00333 public:
00334     // Constructor
00335     LineTypes()
00336     {
00337 #if defined(USE_FLTK)
00338         (*this)["solid"]   = FL_SOLID;
00339         (*this)["dash"]    = FL_DASH;
00340         (*this)["dot"]     = FL_DOT;
00341         (*this)["dashdot"] = FL_DASHDOT;
00342 #elif defined(USE_WXWIDGETS)
00343         (*this)["solid"]   = wxSOLID;
00344         (*this)["dash"]    = wxLONG_DASH;
00345         (*this)["dot"]     = wxDOT;
00346         (*this)["dashdot"] = wxDOT_DASH;
00347 #endif
00348     }
00349 
00350     // Operators
00351     int operator() (char const * Name)
00352     {
00353         if (Name==NULL) throw new Fatal("GUI::LineTypes(): Name must not be NULL");
00354         LineTypes_t::const_iterator p = this->find(Name);
00355         if (p==this->end()) throw new Fatal("GUI::LineTypes(): Linetype '%s' is not available",Name);
00356         return p->second;
00357     }
00358 };
00359 
00360 // Allocate linetypes
00361 LineTypes Lty;
00362 
00363 
00365 
00366 
00367 class PenType
00368 {
00369 public:
00370     // Constructors
00371     PenType (char const * ClrName="black", char const * LtyName="solid", int Lwd=1) { Set(ClrName,LtyName,Lwd); }
00372     PenType (unsigned char R, unsigned char G, unsigned char B, char const * LtyName="solid", int Lwd=1) { Set(R,G,B,  LtyName,Lwd); }
00373 
00374     // Methods
00375     void Set (char const * ClrName, char const * LtyName="solid", int Lwd=1)
00376     {
00377 #if defined(USE_FLTK)
00378         clr = Clr(ClrName);
00379         lty = Lty(LtyName);
00380         lwd = Lwd;
00381 #elif defined(USE_WXWIDGETS)
00382         pen .SetColour (Clr(ClrName));
00383         pen .SetStyle  (Lty(LtyName));
00384         pen .SetWidth  (Lwd);
00385         spen.SetColour (Clr(ClrName));
00386         spen.SetStyle  (Lty("solid"));
00387         spen.SetWidth  (1);
00388 #endif
00389     }
00390 
00391     void Set (unsigned char R, unsigned char G, unsigned char B, char const * LtyName="solid", int Lwd=1)
00392     {
00393 #if defined(USE_FLTK)
00394         clr = Clr(R,G,B);
00395         lty = Lty(LtyName);
00396         lwd = Lwd;
00397 #elif defined(USE_WXWIDGETS)
00398         pen .SetColour (Clr(R,G,B));
00399         pen .SetStyle  (Lty(LtyName));
00400         pen .SetWidth  (Lwd);
00401         spen.SetColour (Clr(R,G,B));
00402         spen.SetStyle  (Lty("solid"));
00403         spen.SetWidth  (1);
00404 #endif
00405     }
00406 
00407     void Activate (DeviceContext & DC, bool ForceSolid=false)
00408     {
00409 #if defined(USE_FLTK)
00410         fl_color (clr);
00411         if (ForceSolid) fl_line_style (FL_SOLID, 1);
00412         else            fl_line_style (lty, lwd);
00413 #elif defined(USE_WXWIDGETS)
00414         if (ForceSolid) DC.SetPen (spen);
00415         else            DC.SetPen (pen);
00416 #endif
00417     }
00418 
00419     // Data
00420 #if defined(USE_FLTK)
00421     Fl_Color clr;
00422     int      lty;
00423     int      lwd;
00424 #elif defined(USE_WXWIDGETS)
00425     wxPen    pen;
00426     wxPen    spen; // solid pen with the same color and width=1
00427 #endif
00428 };
00429 
00430 PenType Black("black", "solid", 1);
00431 
00432 
00434 
00435 
00436 typedef std::map<String,PenType> Pens_t;
00437 
00438 class Pens : public Pens_t
00439 {
00440 public:
00441     // Constructor
00442     Pens()
00443     {
00444         (*this)["black_solid_1"] = PenType("black","solid",1);
00445         (*this)["red_solid_1"]   = PenType("red",  "solid",1);
00446         (*this)["green_solid_1"] = PenType("green","solid",1);
00447         (*this)["blue_solid_1"]  = PenType("blue", "solid",1);
00448     }
00449 
00450     // Operators
00451     PenType operator() (char const * Name)
00452     {
00453         Pens_t::const_iterator p = this->find(Name);
00454 
00455         // add new pen
00456         if (p==this->end())
00457         {
00458             // replace "_" with spaces
00459             String name(Name);
00460             size_t pos = name.find_first_of("_");
00461             while (pos!=String::npos)
00462             {
00463                 name[pos] = ' ';
00464                 pos = name.find_first_of("_",pos+1);
00465             }
00466 
00467             // parse clr, lty, and lwd
00468             std::istringstream iss(name);
00469             String clr, lty;
00470             int    lwd;
00471             iss >> clr >> lty >> lwd;
00472 
00473             // add new pen
00474             PenType pen(clr.CStr(),lty.CStr(),lwd);
00475             (*this)[Name] = pen;
00476             return pen;
00477         }
00478         else return p->second;
00479     }
00480 };
00481 
00482 // Allocate pens
00483 Pens Pen;
00484 
00485 
00487 
00488 
00489 class FontType
00490 {
00491 public:
00492     // Constructor
00493     FontType (char const * FntName="arial", int Size=10, bool Bold=false, bool Italic=false) { Set(FntName,Size,Bold,Italic); }
00494 
00495     // Methods
00496     void Set (char const * FntName, int Size, bool Bold, bool Italic)
00497     {
00498 #if defined(USE_FLTK)
00499         if (strcmp(FntName,"arial")==0)
00500         {
00501             if (Bold && Italic) type = FL_HELVETICA_BOLD_ITALIC;
00502             else if (Bold)      type = FL_HELVETICA_BOLD;
00503             else if (Italic)    type = FL_HELVETICA_ITALIC;
00504             else                type = FL_HELVETICA;
00505         }
00506         else if (strcmp(FntName,"courier")==0)
00507         {
00508             if (Bold && Italic) type = FL_COURIER_BOLD_ITALIC;
00509             else if (Bold)      type = FL_COURIER_BOLD;
00510             else if (Italic)    type = FL_COURIER_ITALIC;
00511             else                type = FL_COURIER;
00512         }
00513         else throw new Fatal("GUI::FontType::FontType: Font named '%s' is not available",FntName);
00514         size = Size;
00515 #elif defined(USE_WXWIDGETS)
00516         if      (strcmp(FntName,"arial")  ==0) font.SetFamily (wxFONTFAMILY_ROMAN);
00517         else if (strcmp(FntName,"courier")==0) font.SetFamily (wxFONTFAMILY_TELETYPE);
00518         else throw new Fatal("GUI::FontType::FontType: Font named '%s' is not available",FntName);
00519         if (Bold)   font.SetWeight (wxFONTWEIGHT_BOLD);
00520         if (Italic) font.SetStyle  (wxFONTSTYLE_ITALIC);
00521         font.SetPointSize (Size);
00522 #endif
00523     }
00524 
00525     void Activate (DeviceContext & DC)
00526     {
00527 #if defined(USE_FLTK)
00528         fl_font (type, size);
00529 #elif defined(USE_WXWIDGETS)
00530         DC.SetFont (font);
00531 #endif
00532     }
00533 
00534     // Data
00535 #if defined(USE_FLTK)
00536     int type;
00537     int size;
00538 #elif defined(USE_WXWIDGETS)
00539     wxFont font;
00540 #endif
00541 };
00542 
00543 
00545 
00546 
00547 typedef std::map<String,FontType> Fonts_t;
00548 
00549 class Fonts : public Fonts_t
00550 {
00551 public:
00552     // Constructor
00553     Fonts () : _initialized(false) {}
00554 
00555     // Initialize
00556     void Initialize ()
00557     {
00558         (*this)["arial_10_n"]    = FontType("arial",   10, false, false);
00559         (*this)["arial_10_b"]    = FontType("arial",   10, true,  false);
00560         (*this)["arial_10_i"]    = FontType("arial",   10, false, true);
00561         (*this)["arial_10_bi"]   = FontType("arial",   10, true,  true);
00562         (*this)["courier_10_n"]  = FontType("courier", 10, false, false);
00563         (*this)["courier_10_b"]  = FontType("courier", 10, true,  false);
00564         (*this)["courier_10_i"]  = FontType("courier", 10, false, true);
00565         (*this)["courier_10_bi"] = FontType("courier", 10, true,  true);
00566         _initialized = true;
00567     }
00568 
00569     // Operators
00570     FontType operator() (char const * Name)
00571     {
00572         if (_initialized) Initialize();
00573 
00574         Fonts_t::const_iterator p = this->find(Name);
00575 
00576         // add new font
00577         if (p==this->end())
00578         {
00579             // replace "_" with spaces
00580             String name(Name);
00581             size_t pos = name.find_first_of("_");
00582             while (pos!=String::npos)
00583             {
00584                 name[pos] = ' ';
00585                 pos = name.find_first_of("_",pos+1);
00586             }
00587 
00588             // parse fontname, size, bold, italic
00589             std::istringstream iss(name);
00590             String fntname, key;
00591             int    size;
00592             iss >> fntname >> size >> key;
00593             bool bold   = false;
00594             bool italic = false;
00595             if (key.size()==1)
00596             {
00597                 if (key[0]=='b') bold   = true;
00598                 if (key[0]=='i') italic = true;
00599             }
00600             else if (key.size()==2)
00601             {
00602                 if (key[0]=='b') bold   = true;
00603                 if (key[1]=='i') italic = true;
00604             }
00605             else throw new Fatal("GUI::Fonts(): key for bold/italic == %d is invalid (must be: n, b, i, bi)",key.CStr());
00606 
00607             // add new font
00608             FontType font(fntname.CStr(),size,bold,italic);
00609             (*this)[Name] = font;
00610             return font;
00611         }
00612         else return p->second;
00613     }
00614 private:
00615     bool _initialized;
00616 };
00617 
00618 // Allocate fonts
00619 Fonts Fnt;
00620 
00621 
00623 
00624 
00625 #if defined(USE_FLTK)
00626 
00627     // Circle
00628     #define GUI_DRAW_CIRCLE(dc,x,y,r) fl_circle (x, y, r);
00629 
00630     // Filled circle
00631     #define GUI_DRAW_FCIRCLE(dc,x,y,r) fl_pie (x-r, y-r, 2*r+1, 2*r+1, 0, 360);
00632 
00633     // Line
00634     #define GUI_DRAW_LINE(dc,x0,y0,x1,y1) fl_line (x0,y0, x1,y1);
00635 
00636     // Text
00637     #define GUI_DRAW_TEXT(dc,t,x,y,align) {                    \
00638         if      (align<0) fl_draw (t,x,y,0,0,FL_ALIGN_LEFT);   \
00639         else if (align>0) fl_draw (t,x,y,0,0,FL_ALIGN_RIGHT);  \
00640         else              fl_draw (t,x,y,0,0,FL_ALIGN_CENTER); }
00641 
00642     // Square (centered at x,y)
00643     #define GUI_DRAW_SQUARE(dc,x,y,l) fl_rect (x-l/2, y-l/2, l, l);
00644 
00645     // Filled square (centered at x,y)
00646     #define GUI_DRAW_FSQUARE(dc,x,y,l) fl_rectf (x-l/2, y-l/2, l, l);
00647 
00648     // Rectangle
00649     #define GUI_DRAW_RECT(dc,x,y,w,h) fl_rect (x, y, w, h);
00650 
00651     // Filled rectangle
00652     #define GUI_DRAW_FRECT(dc,x,y,w,h) fl_rectf (x, y, w, h);
00653 
00654     // Add width of text to p
00655     #define GUI_DRAW_ADD_WIDTH(dc,t,p) p += fl_width(t);
00656 
00657 #elif defined(USE_WXWIDGETS)
00658 
00659     // Circle
00660     #define GUI_DRAW_CIRCLE(dc,x,y,r) dc.DrawCircle (x, y, r);
00661 
00662     // Filled circle
00663     #define GUI_DRAW_FCIRCLE(dc,x,y,r) {                \
00664         dc.SetBrush (wxBrush(dc.GetPen().GetColour())); \
00665         dc.DrawCircle (x, y, r);                        \
00666         dc.SetBrush ((*wxTRANSPARENT_BRUSH));           }
00667 
00668     // Line
00669     #define GUI_DRAW_LINE(dc,x0,y0,x1,y1) dc.DrawLine (x0,y0, x1,y1);
00670 
00671     // Text
00672     #define GUI_DRAW_TEXT(dc,t,x,y,align) {                \
00673         wxCoord wid,hei;                                   \
00674         dc.GetTextExtent (t,&wid,&hei);                    \
00675         if      (align<0) dc.DrawText (t,x,      y-hei/2); \
00676         else if (align>0) dc.DrawText (t,x-wid,  y-hei/2); \
00677         else              dc.DrawText (t,x-wid/2,y-hei/2); }
00678 
00679     // Square (centered at x,y)
00680     #define GUI_DRAW_SQUARE(dc,x,y,l) dc.DrawRectangle (x-l/2, y-l/2, l, l);
00681 
00682     // Filled square (centered at x,y)
00683     #define GUI_DRAW_FSQUARE(dc,x,y,l) {                \
00684         dc.SetBrush (wxBrush(dc.GetPen().GetColour())); \
00685         dc.DrawRectangle (x-l/2, y-l/2, l, l);          \
00686         dc.SetBrush ((*wxTRANSPARENT_BRUSH));           }
00687 
00688     // Rectangle
00689     #define GUI_DRAW_RECT(dc,x,y,w,h) dc.DrawRectangle (x, y, w, h);
00690 
00691     // Filled rectangle
00692     #define GUI_DRAW_FRECT(dc,x,y,w,h) {                \
00693         dc.SetBrush (wxBrush(dc.GetPen().GetColour())); \
00694         dc.DrawRectangle (x, y, w, h);                  \
00695         dc.SetBrush ((*wxTRANSPARENT_BRUSH));           }
00696 
00697     // Add width of text to p
00698     #define GUI_DRAW_ADD_WIDTH(dc,t,p) { \
00699         wxCoord wid,hei;                 \
00700         dc.GetTextExtent (t,&wid,&hei);  \
00701         p += wid;                        }
00702 
00703 #endif
00704 
00705 }; // namespace GUI
00706 
00707 #endif // MECHSYS_GUI_COMMON_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines