![]() |
MechSys
1.0
Computing library for simulations in continuum and discrete mechanics
|
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