diff --git a/CMakeLists.txt b/CMakeLists.txt index c0bfad1385208a358d63925b0e45d412e098047e..bd8fe3846246e11fc18d6cfac1a3343f02ffcb9a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,6 @@ option(ENABLE_CGNS "Enable CGNS mesh export" OFF) option(ENABLE_CHACO "Enable Chaco mesh partitioner" ${DEFAULT}) option(ENABLE_DINTEGRATION "Enable discrete integration and levelsets" ${DEFAULT}) option(ENABLE_FLTK "Build FLTK GUI" ${DEFAULT}) -option(ENABLE_FL_TREE "Enable FLTK tree browser widget" ${DEFAULT}) option(ENABLE_FOURIER_MODEL "Enable Fourier geometrical models" OFF) option(ENABLE_GMM "Enable GMM linear algebra solvers" ${DEFAULT}) option(ENABLE_GRAPHICS "Compile-in OpenGL graphics even if there is no GUI" OFF) @@ -399,23 +398,6 @@ if(ENABLE_FLTK) endif(FLTK_PNG) endif(FLTK_FOUND) endif(NOT HAVE_FLTK) - if(HAVE_FLTK) - if(ENABLE_NATIVE_FILE_CHOOSER) - if(NOT FLTK_VERSION OR FLTK_VERSION EQUAL 1.1) - add_subdirectory(contrib/NativeFileChooser) - include_directories(contrib/NativeFileChooser) - add_definitions(-DFLTK1) - endif(NOT FLTK_VERSION OR FLTK_VERSION EQUAL 1.1) - set_config_option(HAVE_NATIVE_FILE_CHOOSER "NativeFileChooser") - endif(ENABLE_NATIVE_FILE_CHOOSER) - if(ENABLE_FL_TREE) - if(NOT FLTK_VERSION OR FLTK_VERSION EQUAL 1.1) - add_subdirectory(contrib/Fl_Tree) - include_directories(contrib/Fl_Tree) - endif(NOT FLTK_VERSION OR FLTK_VERSION EQUAL 1.1) - set_config_option(HAVE_FL_TREE "FlTree") - endif(ENABLE_FL_TREE) - endif(HAVE_FLTK) elseif(ENABLE_QT) find_package(Qt4) set(QT_USE_QTOPENGL TRUE) @@ -427,10 +409,23 @@ elseif(ENABLE_QT) endif(QT_FOUND) endif(ENABLE_FLTK) +if(ENABLE_NATIVE_FILE_CHOOSER) + set_config_option(HAVE_NATIVE_FILE_CHOOSER "NativeFileChooser") +endif(ENABLE_NATIVE_FILE_CHOOSER) + +if(ENABLE_ONELAB) + set_config_option(HAVE_ONELAB "OneLab") + if(ENABLE_ONELAB_METAMODEL) + add_subdirectory(contrib/onelab) + include_directories(contrib/onelab) + set_config_option(HAVE_ONELAB_METAMODEL "OneLabMetamodel") + endif(ENABLE_ONELAB_METAMODEL) +endif(ENABLE_ONELAB) + if(HAVE_FLTK OR HAVE_QT OR ENABLE_GRAPHICS) - if(NOT HAVE_MESH OR NOT HAVE_POST OR NOT HAVE_PLUGINS) - message(SEND_ERROR "Cannot compile GUI without Mesh, Post or Plugin modules") - endif(NOT HAVE_MESH OR NOT HAVE_POST OR NOT HAVE_PLUGINS) + if(NOT HAVE_MESH OR NOT HAVE_POST OR NOT HAVE_PLUGINS OR NOT HAVE_ONELAB) + message(SEND_ERROR "Cannot compile GUI without Mesh, Post, Plugin or OneLab") + endif(NOT HAVE_MESH OR NOT HAVE_POST OR NOT HAVE_PLUGINS OR NOT HAVE_ONELAB) if(FLTK_JPEG) set_config_option(HAVE_LIBJPEG "Jpeg(Fltk)") @@ -909,15 +904,6 @@ if(ENABLE_ACIS) endif(ACIS_LIB) endif(ENABLE_ACIS) -if(ENABLE_ONELAB) - set_config_option(HAVE_ONELAB "OneLab") - if(ENABLE_ONELAB_METAMODEL) - add_subdirectory(contrib/onelab) - include_directories(contrib/onelab) - set_config_option(HAVE_ONELAB_METAMODEL "OneLabMetamodel") - endif(ENABLE_ONELAB_METAMODEL) -endif(ENABLE_ONELAB) - check_function_exists(vsnprintf HAVE_VSNPRINTF) if(NOT HAVE_VSNPRINTF) set_config_option(HAVE_NO_VSNPRINTF "NoVsnprintf") diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp index ec867de016c47eeca4a478a17af358cd1fb20676..a87f4170658e0a08731bd86c414423051d36db61 100644 --- a/Common/CommandLine.cpp +++ b/Common/CommandLine.cpp @@ -20,12 +20,10 @@ #if defined(HAVE_FLTK) #include <FL/Fl.H> -#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 1) && (FL_PATCH_VERSION > 6) +#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION >= 3) // OK -#elif (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3) -// also OK #else -#error "Gmsh requires FLTK >= 1.1.7 or FLTK 1.3.x" +#error "Gmsh requires FLTK >= 1.3" #endif #endif diff --git a/Common/Context.cpp b/Common/Context.cpp index 43cd9ece96bf093e1c8d2261e7e16a563e4af135..0d687f912f2e466203ba505d06ecd8461274ea3c 100644 --- a/Common/Context.cpp +++ b/Common/Context.cpp @@ -39,7 +39,7 @@ CTX::CTX() outputFileName = ""; bgmFileName = ""; createAppendMeshStatReport = 0; - launchOnelabAtStartup = -2; + launchSolverAtStartup = -1; lc = 1.; min[0] = min[1] = min[2] = max[2] = 0.; max[0] = max[1] = 1.; // for nice view when adding point in new model diff --git a/Common/Context.h b/Common/Context.h index efe936dc481d3c5c7ddf26409cd0aeca1517a65d..f0bc9a6a99f3fb34ae201ecb251132f4a8fb7830 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -82,8 +82,8 @@ class CTX { std::vector<std::string> recentFiles; // create mesh statistics report (0: do nothing, 1: create, 2: append) int createAppendMeshStatReport; - // should we launch the onelab interface at startup? - int launchOnelabAtStartup ; + // should we launch a solver at startup? + int launchSolverAtStartup ; // save session/option file on exit? int sessionSave, optionsSave; // ask confirmation when overwriting files? @@ -103,9 +103,9 @@ class CTX { // show tootips in the GUI? int tooltips; // position and size of various windows in the GUI - int menuPosition[2], glPosition[2], glSize[2], msgSize; + int glPosition[2], glSize[2], msgSize; int optPosition[2], visPosition[2], hotPosition[2], clipPosition[2], manipPosition[2]; - int statPosition[2], ctxPosition[2], solverPosition[2], solverSize[2]; + int statPosition[2], ctxPosition[2]; int pluginPosition[2], pluginSize[2], fieldPosition[2], fieldSize[2]; int fileChooserPosition[2], extraPosition[2], extraSize[2]; // use the system menu bar on Mac OS X? diff --git a/Common/CreateFile.cpp b/Common/CreateFile.cpp index 2a04beffb9005fdaaf07da73932b34fbc809c11b..56f685cdc752b44f1fdc18c0156b8bc583ae071b 100644 --- a/Common/CreateFile.cpp +++ b/Common/CreateFile.cpp @@ -174,7 +174,7 @@ void CreateOutputFile(const std::string &fileName, int format, bool redraw) bool error = false; if(redraw) - Msg::StatusBar(2, true, "Writing '%s'...", name.c_str()); + Msg::StatusBar(true, "Writing '%s'...", name.c_str()); switch (format) { @@ -531,7 +531,7 @@ void CreateOutputFile(const std::string &fileName, int format, bool redraw) CTX::instance()->printing = 0; if(redraw && !error) - Msg::StatusBar(2, true, "Done writing '%s'", name.c_str()); + Msg::StatusBar(true, "Done writing '%s'", name.c_str()); #if defined(HAVE_OPENGL) if(redraw) drawContext::global()->draw(); diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index ae36bcf15bb51a25744c76f9ba6a28a56732e9e5..7a1447cd92d476e56279584fc22531f6346dcfc5 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -505,10 +505,6 @@ StringXNumber GeneralOptions_Number[] = { "Maximum model coordinate along the Y-axis (read-only)" }, { F, "MaxZ" , opt_general_zmax , 0. , "Maximum model coordinate along the Z-axis (read-only)" }, - { F|S, "MenuPositionX" , opt_general_menu_position0 , 800. , - "Horizontal position (in pixels) of the upper left corner of the menu window" }, - { F|S, "MenuPositionY" , opt_general_menu_position1 , 50. , - "Vertical position (in pixels) of the upper left corner of the menu window" }, { F|S, "MessageHeight" , opt_general_message_size , 300. , "Height (in pixels) of the message console" }, { F, "MinX" , opt_general_xmin , 0. , @@ -607,15 +603,6 @@ StringXNumber GeneralOptions_Number[] = { " centered)" }, { F|O, "SmallAxesSize" , opt_general_small_axes_size , 30. , "Size (in pixels) of small axes" }, - { F|S, "SolverPositionX" , opt_general_solver_position0 , 650. , - "Horizontal position (in pixels) of the upper left corner of the solver " - "window" }, - { F|S, "SolverPositionY" , opt_general_solver_position1 , 150. , - "Vertical position (in pixels) of the upper left corner of the solver window" }, - { F|S, "SolverHeight" , opt_general_solver_size1 , 400. , - "Height (in pixels) of the solver window" }, - { F|S, "SolverWidth" , opt_general_solver_size0 , 300. , - "Width (in pixels) of the solver window" }, { F|S, "StatisticsPositionX" , opt_general_statistics_position0 , 650. , "Horizontal position (in pixels) of the upper left corner of the statistic " "window" }, diff --git a/Common/Gmsh.cpp b/Common/Gmsh.cpp index 573931a542dddc7d04b618d15c21d7b5d23f9d36..41a5d9a6cfb516521729ba9709b7916fffef58fc 100644 --- a/Common/Gmsh.cpp +++ b/Common/Gmsh.cpp @@ -38,9 +38,9 @@ #if defined(HAVE_FLTK) #include "FlGui.h" -#include "menuWindow.h" +#include "graphicWindow.h" #include "drawContext.h" -#include "onelabWindow.h" +#include "onelabGroup.h" #endif int GmshInitialize(int argc, char **argv) @@ -235,15 +235,12 @@ int GmshFLTK(int argc, char **argv) // init first context switch (CTX::instance()->initialContext) { - case 1: FlGui::instance()->menu->setContext(menu_geometry, 0); break; - case 2: FlGui::instance()->menu->setContext(menu_mesh, 0); break; - case 3: FlGui::instance()->menu->setContext(menu_solver, 0); break; - case 4: FlGui::instance()->menu->setContext(menu_post, 0); break; + case 1: FlGui::instance()->openModule("Geometry"); break; + case 2: FlGui::instance()->openModule("Mesh"); break; + case 3: FlGui::instance()->openModule("Solver"); break; + case 4: FlGui::instance()->openModule("Post-processing"); break; default: // automatic - if(PView::list.size()) - FlGui::instance()->menu->setContext(menu_post, 0); - else - FlGui::instance()->menu->setContext(menu_geometry, 0); + if(PView::list.size()) FlGui::instance()->openModule("Post-processing"); break; } @@ -256,16 +253,14 @@ int GmshFLTK(int argc, char **argv) Msg::Error("Invalid background mesh (no view)"); } -#if defined(HAVE_ONELAB) // listen to external solvers if(CTX::instance()->solver.listen){ onelab::localNetworkClient *c = new onelab::localNetworkClient("Listen", ""); c->run(); } - if(CTX::instance()->launchOnelabAtStartup != -2){ - solver_cb(0, (void*)CTX::instance()->launchOnelabAtStartup); - } -#endif + + // launch solver (if requested) and fill onelab tree + solver_cb(0, (void*)CTX::instance()->launchSolverAtStartup); // loop return FlGui::instance()->run(); diff --git a/Common/GmshConfig.h.in b/Common/GmshConfig.h.in index 4d917e3e9632b818b564e6d6add9bd88a24cd264..79b05ce051379ff6ea23c028cb55aa13c4fac558 100644 --- a/Common/GmshConfig.h.in +++ b/Common/GmshConfig.h.in @@ -18,7 +18,6 @@ #cmakedefine HAVE_DLOPEN #cmakedefine HAVE_DINTEGRATION #cmakedefine HAVE_FLTK -#cmakedefine HAVE_FL_TREE #cmakedefine HAVE_FOURIER_MODEL #cmakedefine HAVE_GMM #cmakedefine HAVE_GMP diff --git a/Common/GmshMessage.cpp b/Common/GmshMessage.cpp index 806bafc44a2ffe99dca9bfd2d6613be3765f1aec..0a8ae573f187562d694816ef2f7d1eaf0e77b060 100644 --- a/Common/GmshMessage.cpp +++ b/Common/GmshMessage.cpp @@ -387,10 +387,9 @@ void Msg::Direct(int level, const char *fmt, ...) } } -void Msg::StatusBar(int num, bool log, const char *fmt, ...) +void Msg::StatusBar(bool log, const char *fmt, ...) { if(_commRank || _verbosity < 4) return; - if(num < 1 || num > 3) return; char str[5000]; va_list args; @@ -404,8 +403,8 @@ void Msg::StatusBar(int num, bool log, const char *fmt, ...) #if defined(HAVE_FLTK) if(FlGui::available()){ if(log) FlGui::instance()->check(); - if(!log || num != 2 || _verbosity > 4) - FlGui::instance()->setStatus(str, num - 1); + if(!log || _verbosity > 4) + FlGui::instance()->setStatus(str); if(log){ std::string tmp = std::string("Info : ") + str; FlGui::instance()->addMessage(tmp.c_str()); @@ -419,6 +418,20 @@ void Msg::StatusBar(int num, bool log, const char *fmt, ...) } } +void Msg::StatusGl(const char *fmt, ...) +{ +#if defined(HAVE_FLTK) + if(_commRank) return; + char str[5000]; + va_list args; + va_start(args, fmt); + vsnprintf(str, sizeof(str), fmt, args); + va_end(args); + if(FlGui::available()) + FlGui::instance()->setStatus(str, true); +#endif +} + void Msg::Debug(const char *fmt, ...) { if(_verbosity < 99) return; @@ -791,7 +804,6 @@ void Msg::ExchangeOnelabParameter(const std::string &key, { #if defined(HAVE_ONELAB) if(!_onelabClient || val.empty()) return; - CTX::instance()->launchOnelabAtStartup = -1; std::string name = _getParameterName(key, copt); @@ -873,7 +885,6 @@ void Msg::ExchangeOnelabParameter(const std::string &key, { #if defined(HAVE_ONELAB) if(!_onelabClient || val.empty()) return; - CTX::instance()->launchOnelabAtStartup = -1; std::string name = _getParameterName(key, copt); @@ -919,10 +930,11 @@ void Msg::ImportPhysicalsAsOnelabRegions() name = std::string("Physical") + ((dim == 3) ? "Volume" : (dim == 2) ? "Surface" : (dim == 1) ? "Line" : "Point") + num.str(); - name.insert(0, "Gmsh/Physical groups/"); + name.insert(0, "Gmsh parameters/Physical groups/"); onelab::region p(name, num.str()); p.setDimension(dim); p.setReadOnly(true); + p.setVisible(false); p.setAttribute("Closed", "1"); _onelabClient->set(p); } diff --git a/Common/GmshMessage.h b/Common/GmshMessage.h index 27431e42aeb453e7e525b455988dc1ab1dd52152..38b18916e20cfd5ccf4cd2a5bc8d8feb7b98a1ec 100644 --- a/Common/GmshMessage.h +++ b/Common/GmshMessage.h @@ -69,7 +69,8 @@ class Msg { static void Info(const char *fmt, ...); static void Direct(const char *fmt, ...); static void Direct(int level, const char *fmt, ...); - static void StatusBar(int num, bool log, const char *fmt, ...); + static void StatusBar(bool log, const char *fmt, ...); + static void StatusGl(const char *fmt, ...); static void Debug(const char *fmt, ...); static void ProgressMeter(int n, int N, bool log, const char *fmt, ...); static void SetProgressMeterStep(int step){ _progressMeterStep = step; } diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp index 9b1bb7a938b999c41edbb1b38bdb8a2becf76af4..72098a2af4414f1f220d1965e3032b703b720b62 100644 --- a/Common/OpenFile.cpp +++ b/Common/OpenFile.cpp @@ -37,8 +37,8 @@ #if defined(HAVE_FLTK) #include <FL/fl_ask.H> #include "FlGui.h" -#include "onelabWindow.h" -#include "menuWindow.h" +#include "onelabGroup.h" +#include "graphicWindow.h" #include "drawContext.h" #endif @@ -257,7 +257,7 @@ int MergeFile(const std::string &fileName, bool warnIfMissing) if(!fgets(header, sizeof(header), fp)) return 0; fclose(fp); - Msg::StatusBar(2, true, "Reading '%s'...", fileName.c_str()); + Msg::StatusBar(true, "Reading '%s'...", fileName.c_str()); std::vector<std::string> split = SplitFileName(fileName); std::string noExt = split[0] + split[1], ext = split[2]; @@ -379,7 +379,7 @@ int MergeFile(const std::string &fileName, bool warnIfMissing) std::vector<std::string> split = SplitFileName(fileName); GModel::current()->setName(""); status = MergeFile(split[0] + split[1] + ".geo"); - CTX::instance()->launchOnelabAtStartup = 0; + CTX::instance()->launchSolverAtStartup = 0; return status; } #endif @@ -445,7 +445,7 @@ int MergeFile(const std::string &fileName, bool warnIfMissing) Msg::ImportPhysicalsAsOnelabRegions(); if(!status) Msg::Error("Error loading '%s'", fileName.c_str()); - Msg::StatusBar(2, true, "Done reading '%s'", fileName.c_str()); + Msg::StatusBar(true, "Done reading '%s'", fileName.c_str()); // merge the associated option file if there is one if(!StatFile(fileName + ".opt")) @@ -606,7 +606,7 @@ void OpenProject(const std::string &fileName) CTX::instance()->recentFiles.resize(5); #if defined(HAVE_FLTK) if(FlGui::available()) - FlGui::instance()->menu->fillRecentHistoryMenu(); + FlGui::instance()->graph[0]->fillRecentHistoryMenu(); #endif } diff --git a/Common/Options.cpp b/Common/Options.cpp index 78013e28c1e1106f946d6e5dc65e109bd68a2e2a..a47fb543aa5b981a1a8bd45be7a25158ca003d70 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -41,12 +41,13 @@ #if defined(HAVE_FLTK) #include <FL/Fl_Tooltip.H> #include "FlGui.h" -#include "menuWindow.h" #include "graphicWindow.h" #include "optionWindow.h" #include "manipWindow.h" #include "contextWindow.h" #include "clippingWindow.h" +#include "onelabGroup.h" +#include "viewButton.h" #endif // General routines for string options @@ -1279,9 +1280,9 @@ std::string opt_view_name(OPT_ARGS_STR) if((i == num || PView::list[i]->getAliasOf() == view->getNum() || PView::list[i]->getNum() == view->getAliasOf()) && - i < (int)FlGui::instance()->menu->toggle.size()) { - FlGui::instance()->menu->toggle[i]->copy_label(data->getName().c_str()); - FlGui::instance()->menu->toggle[i]->redraw(); + FlGui::instance()->onelab->getViewButton(i)) { + FlGui::instance()->onelab->getViewButton(i)->copy_label(data->getName()); + FlGui::instance()->onelab->getViewButton(i)->redraw(); } } } @@ -1802,48 +1803,6 @@ double opt_general_graphics_size1(OPT_ARGS_NUM) return CTX::instance()->glSize[1]; } -double opt_general_menu_position0(OPT_ARGS_NUM) -{ - if(action & GMSH_SET) - CTX::instance()->menuPosition[0] = (int)val; - return CTX::instance()->menuPosition[0]; -} - -double opt_general_menu_position1(OPT_ARGS_NUM) -{ - if(action & GMSH_SET) - CTX::instance()->menuPosition[1] = (int)val; - return CTX::instance()->menuPosition[1]; -} - -double opt_general_solver_position0(OPT_ARGS_NUM) -{ - if(action & GMSH_SET) - CTX::instance()->solverPosition[0] = (int)val; - return CTX::instance()->solverPosition[0]; -} - -double opt_general_solver_position1(OPT_ARGS_NUM) -{ - if(action & GMSH_SET) - CTX::instance()->solverPosition[1] = (int)val; - return CTX::instance()->solverPosition[1]; -} - -double opt_general_solver_size0(OPT_ARGS_NUM) -{ - if(action & GMSH_SET) - CTX::instance()->solverSize[0] = (int)val; - return CTX::instance()->solverSize[0]; -} - -double opt_general_solver_size1(OPT_ARGS_NUM) -{ - if(action & GMSH_SET) - CTX::instance()->solverSize[1] = (int)val; - return CTX::instance()->solverSize[1]; -} - double opt_general_context_position0(OPT_ARGS_NUM) { if(action & GMSH_SET) @@ -2463,12 +2422,12 @@ double opt_general_orthographic(OPT_ARGS_NUM) if(CTX::instance()->ortho){ FlGui::instance()->options->general.choice[2]->value(0); if(FlGui::available()) - Msg::StatusBar(2, false, "Orthographic projection"); + Msg::StatusBar(false, "Orthographic projection"); } else{ FlGui::instance()->options->general.choice[2]->value(1); if(FlGui::available()) - Msg::StatusBar(2, false, "Perspective projection"); + Msg::StatusBar(false, "Perspective projection"); } } #endif @@ -2483,13 +2442,13 @@ double opt_general_mouse_selection(OPT_ARGS_NUM) if(FlGui::available() && (action & GMSH_GUI)) { if(CTX::instance()->mouseSelection){ if(FlGui::available()) - Msg::StatusBar(2, false, "Mouse selection ON"); + Msg::StatusBar(false, "Mouse selection ON"); for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++) FlGui::instance()->graph[i]->butt[9]->color(FL_BACKGROUND_COLOR); } else{ if(FlGui::available()) - Msg::StatusBar(2, false, "Mouse selection OFF"); + Msg::StatusBar(false, "Mouse selection OFF"); for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++) FlGui::instance()->graph[i]->butt[9]->color(FL_RED); } @@ -6555,8 +6514,8 @@ double opt_view_visible(OPT_ARGS_NUM) } #if defined(HAVE_FLTK) if(FlGui::available() && (action & GMSH_GUI) && num >= 0 && - num < (int)FlGui::instance()->menu->toggle.size()) - FlGui::instance()->menu->toggle[num]->value(opt->visible); + FlGui::instance()->onelab->getViewButton(num)) + FlGui::instance()->onelab->getViewButton(num)->value(opt->visible); #endif return opt->visible; #else diff --git a/Common/Options.h b/Common/Options.h index 2d16e401e8e152c2d7ac126de8387f120d7edaf0..af3918cdd230dec1a88aa774890843b0c8c9af45 100644 --- a/Common/Options.h +++ b/Common/Options.h @@ -103,10 +103,6 @@ double opt_general_graphics_position0(OPT_ARGS_NUM); double opt_general_graphics_position1(OPT_ARGS_NUM); double opt_general_graphics_size0(OPT_ARGS_NUM); double opt_general_graphics_size1(OPT_ARGS_NUM); -double opt_general_solver_position0(OPT_ARGS_NUM); -double opt_general_solver_position1(OPT_ARGS_NUM); -double opt_general_solver_size0(OPT_ARGS_NUM); -double opt_general_solver_size1(OPT_ARGS_NUM); double opt_general_context_position0(OPT_ARGS_NUM); double opt_general_context_position1(OPT_ARGS_NUM); double opt_general_file_chooser_position0(OPT_ARGS_NUM); @@ -114,8 +110,6 @@ double opt_general_file_chooser_position1(OPT_ARGS_NUM); double opt_general_polygon_offset_always(OPT_ARGS_NUM); double opt_general_polygon_offset_factor(OPT_ARGS_NUM); double opt_general_polygon_offset_units(OPT_ARGS_NUM); -double opt_general_menu_position0(OPT_ARGS_NUM); -double opt_general_menu_position1(OPT_ARGS_NUM); double opt_general_system_menu_bar(OPT_ARGS_NUM); double opt_general_message_size(OPT_ARGS_NUM); double opt_general_option_position0(OPT_ARGS_NUM); diff --git a/Common/onelabUtils.cpp b/Common/onelabUtils.cpp index 2c891e2aebbacb882302ca57b1bd406efaeb7f33..258bf1107cc62911171a986a11fbc563f94e7f75 100644 --- a/Common/onelabUtils.cpp +++ b/Common/onelabUtils.cpp @@ -140,8 +140,8 @@ namespace onelabUtils { } } - // force this to make sure that we remesh, even if a mesh exists and - // we did not actually change a Gmsh parameter + // force this to make sure that we remesh, even if a mesh exists and we did + // not actually change a Gmsh parameter if(changed) onelab::server::instance()->setChanged(true, "Gmsh"); } diff --git a/Fltk/CMakeLists.txt b/Fltk/CMakeLists.txt index 7814c45c19d449c8a7eb9f65464a20a5c55b1aea..11d813af2b320e9696c935da2acbb57ddff9b1a7 100644 --- a/Fltk/CMakeLists.txt +++ b/Fltk/CMakeLists.txt @@ -7,7 +7,6 @@ set(SRC FlGui.cpp graphicWindow.cpp openglWindow.cpp - menuWindow.cpp optionWindow.cpp colorbarWindow.cpp fieldWindow.cpp @@ -24,8 +23,9 @@ set(SRC projectionEditor.cpp classificationEditor.cpp partitionDialog.cpp - onelabWindow.cpp + onelabGroup.cpp inputRegion.cpp + viewButton.cpp ) file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h) diff --git a/Fltk/FlGui.cpp b/Fltk/FlGui.cpp index 755e0f8327359f7efeb380515409927b03715671..9bf64ee85f8cdd4adcf5f7e8b422b85ff17838ce 100644 --- a/Fltk/FlGui.cpp +++ b/Fltk/FlGui.cpp @@ -19,7 +19,6 @@ typedef unsigned long intptr_t; #include <FL/gl.h> #include "FlGui.h" #include "graphicWindow.h" -#include "menuWindow.h" #include "optionWindow.h" #include "fieldWindow.h" #include "pluginWindow.h" @@ -29,7 +28,7 @@ typedef unsigned long intptr_t; #include "clippingWindow.h" #include "manipWindow.h" #include "contextWindow.h" -#include "onelabWindow.h" +#include "onelabGroup.h" #include "aboutWindow.h" #include "colorbarWindow.h" #include "fileDialogs.h" @@ -186,7 +185,7 @@ class drawContextFltk : public drawContextGlobal{ } void resetFontTextures() { -#if defined(__APPLE__) && (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3) +#if defined(__APPLE__) gl_texture_pile_height(1); // force font texture recomputation #endif } @@ -233,17 +232,17 @@ FlGui::FlGui(int argc, char **argv) : _openedThroughMacFinder(false) // add callback to respond to Mac Finder #if defined(__APPLE__) fl_open_callback(OpenProjectMacFinder); -#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3) fl_mac_set_about(help_about_cb, 0); -#endif #endif - // all the windows are contructed (even if some are not displayed) - // since the shortcuts should be valid even for hidden windows, and - // we don't want to test for widget existence every time - menu = new menuWindow(); + // all the windows are contructed (even if some are not displayed) since the + // shortcuts should be valid even for hidden windows, and we don't want to + // test for widget existence every time graph.push_back(new graphicWindow(true, CTX::instance()->numTiles)); + // FIXME: make this cleaner ;-) + onelab = graph.back()->onelab; + #if defined(WIN32) graph[0]->win->icon ((const char*)LoadImage(fl_display, MAKEINTRESOURCE(IDI_ICON), @@ -267,18 +266,12 @@ FlGui::FlGui(int argc, char **argv) : _openedThroughMacFinder(false) graph[0]->win->icon ((const char*)XCreateBitmapFromData(fl_display, DefaultRootWindow(fl_display), gmsh32x32, 32, 32)); - menu->win->icon - ((const char*)XCreateBitmapFromData(fl_display, DefaultRootWindow(fl_display), - gmsh32x32, 32, 32)); #endif - // open graphic window first for correct non-modal behaviour on - // Win32 graph[0]->win->show(1, argv); - menu->win->show(); - // graphic window should have the initial focus (so we can - // e.g. directly loop through time steps with the keyboard) + // graphic window should have the initial focus (so we can e.g. directly loop + // through time steps with the keyboard) //graph[0]->gl[0]->take_focus(); Fl::focus(graph[0]->gl[0]); @@ -302,9 +295,6 @@ FlGui::FlGui(int argc, char **argv) : _openedThroughMacFinder(false) geoContext = new geometryContextWindow(CTX::instance()->deltaFontSize); meshContext = new meshContextWindow(CTX::instance()->deltaFontSize); about = new aboutWindow(); -#if defined(HAVE_ONELAB) && (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3) - onelab = new onelabWindow(CTX::instance()->deltaFontSize); -#endif // init solver plugin stuff callForSolverPlugin(-1); @@ -313,8 +303,6 @@ FlGui::FlGui(int argc, char **argv) : _openedThroughMacFinder(false) for(unsigned int i = 0; i < graph.size(); i++) for(unsigned int j = 0; j < graph[i]->gl.size(); j++) graph[i]->gl[j]->redraw(); - - menu->setContext(menu_geometry, 0); } FlGui *FlGui::_instance = 0; @@ -326,8 +314,7 @@ FlGui *FlGui::instance(int argc, char **argv) // set all options in the new GUI InitOptionsGUI(0); // say welcome! - Msg::StatusBar(1, false, "Geometry"); - Msg::StatusBar(2, false, "Gmsh %s", GetGmshVersion()); + Msg::StatusBar(false, "Gmsh %s", GetGmshVersion()); // log the following for bug reports Msg::Info("-------------------------------------------------------"); Msg::Info("Gmsh version : %s", GetGmshVersion()); @@ -346,9 +333,9 @@ FlGui *FlGui::instance(int argc, char **argv) int FlGui::run() { - // bounding box computation necessary if we run the gui without - // merging any files (e.g. if we build the geometry with python and - // create the gui from the python script) + // bounding box computation necessary if we run the gui without merging any + // files (e.g. if we build the geometry with python and create the gui from + // the python script) SetBoundingBox(); // draw the scene @@ -365,63 +352,40 @@ int FlGui::testGlobalShortcuts(int event) int status = 0; if(Fl::test_shortcut('0')) { - // FIXME: here we should also reset all onelab variables that depend on Gmsh geometry_reload_cb(0, 0); - mod_geometry_cb(0, 0); status = 1; } else if(Fl::test_shortcut('1') || Fl::test_shortcut(FL_F + 1)) { mesh_1d_cb(0, 0); - mod_mesh_cb(0, 0); status = 1; } else if(Fl::test_shortcut('2') || Fl::test_shortcut(FL_F + 2)) { mesh_2d_cb(0, 0); - mod_mesh_cb(0, 0); status = 1; } else if(Fl::test_shortcut('3') || Fl::test_shortcut(FL_F + 3)) { mesh_3d_cb(0, 0); - mod_mesh_cb(0, 0); status = 1; } - // FIXME TEST - //else if(Fl::test_shortcut('4') || Fl::test_shortcut(FL_F + 4)) { - // RecombineMesh(GModel::current()); - // status = 2; - //} else if(Fl::test_shortcut(FL_CTRL + 'q') || Fl::test_shortcut(FL_META + 'q')){ - // only necessary when using the system menu bar, but hey, it - // cannot hurt... + // only necessary when using the system menu bar, but hey, it cannot hurt... file_quit_cb(0, 0); status = 1; } else if(Fl::test_shortcut('g')) { - mod_geometry_cb(0, 0); - Fl::focus(menu->scroll); + FlGui::instance()->openModule("Geometry"); status = 1; } else if(Fl::test_shortcut('m')) { - mod_mesh_cb(0, 0); - Fl::focus(menu->scroll); + FlGui::instance()->openModule("Mesh"); status = 1; } else if(Fl::test_shortcut('s')) { - mod_solver_cb(0, 0); - Fl::focus(menu->scroll); + FlGui::instance()->openModule("Solver"); status = 1; } else if(Fl::test_shortcut('p')) { - mod_post_cb(0, 0); - Fl::focus(menu->scroll); - status = 1; - } - else if(Fl::test_shortcut('<')) { - mod_back_cb(0, 0); - status = 1; - } - else if(Fl::test_shortcut('>')) { - mod_forward_cb(0, 0); + FlGui::instance()->openModule("Post-processing"); status = 1; } else if(Fl::test_shortcut('w')) { @@ -723,14 +687,12 @@ int FlGui::testArrowShortcuts() void FlGui::setGraphicTitle(std::string title) { for(unsigned int i = 0; i < graph.size(); i++){ - if(!i){ - graph[i]->setTitle(title); - } - else{ - std::ostringstream sstream; - sstream << title << " [" << i << "]"; - graph[i]->setTitle(sstream.str()); - } + std::ostringstream sstream; + if(!i) + sstream << "Gmsh - " << title; + else + sstream << "Gmsh - " << title << " [" << i << "]"; + graph[i]->setTitle(sstream.str()); } } @@ -739,8 +701,7 @@ void FlGui::updateViews(bool numberOfViewsHasChanged) for(unsigned int i = 0; i < graph.size(); i++) graph[i]->checkAnimButtons(); if(numberOfViewsHasChanged){ - if(menu->module->value() == 3) - menu->setContext(menu_post, 0); + onelab->rebuildTree(); options->resetBrowser(); options->resetExternalViewList(); fields->loadFieldViewList(); @@ -786,18 +747,18 @@ char FlGui::selectEntity(int type) selectedElements); } -void FlGui::setStatus(const char *msg, int num) +void FlGui::setStatus(const char *msg, bool opengl) { - if(num == 0 || num == 1){ - static char buff[2][1024]; - strncpy(buff[num], msg, sizeof(buff[num]) - 1); - buff[num][sizeof(buff[num]) - 1] = '\0'; + if(!opengl){ + static char buff[1024]; + strncpy(buff, msg, sizeof(buff) - 1); + buff[sizeof(buff) - 1] = '\0'; for(unsigned int i = 0; i < graph.size(); i++){ - graph[i]->label[num]->label(buff[num]); - graph[i]->label[num]->redraw(); + graph[i]->label->label(buff); + graph[i]->label->redraw(); } } - else if(num == 2){ + else{ openglWindow *gl = getCurrentOpenglWindow(); int n = strlen(msg); int i = 0; @@ -816,20 +777,18 @@ void FlGui::setStatus(const char *msg, int num) void FlGui::setProgress(const char *msg, double val, double min, double max) { for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++){ - if(FlGui::instance()->graph[i]->label[1]->value() != val) - FlGui::instance()->graph[i]->label[1]->value(val); - if(FlGui::instance()->graph[i]->label[1]->minimum() != min) - FlGui::instance()->graph[i]->label[1]->minimum(min); - if(FlGui::instance()->graph[i]->label[1]->maximum() != max) - FlGui::instance()->graph[i]->label[1]->maximum(max); - } - setStatus(msg, 1); + if(FlGui::instance()->graph[i]->label->value() != val) + FlGui::instance()->graph[i]->label->value(val); + if(FlGui::instance()->graph[i]->label->minimum() != min) + FlGui::instance()->graph[i]->label->minimum(min); + if(FlGui::instance()->graph[i]->label->maximum() != max) + FlGui::instance()->graph[i]->label->maximum(max); + } + setStatus(msg); } void FlGui::storeCurrentWindowsInfo() { - CTX::instance()->menuPosition[0] = menu->win->x(); - CTX::instance()->menuPosition[1] = menu->win->y(); CTX::instance()->glPosition[0] = graph[0]->win->x(); CTX::instance()->glPosition[1] = graph[0]->win->y(); CTX::instance()->glSize[0] = graph[0]->win->w(); @@ -857,12 +816,6 @@ void FlGui::storeCurrentWindowsInfo() CTX::instance()->manipPosition[1] = manip->win->y(); CTX::instance()->ctxPosition[0] = geoContext->win->x(); CTX::instance()->ctxPosition[1] = meshContext->win->y(); -#if defined(HAVE_ONELAB) && (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3) - CTX::instance()->solverPosition[0] = onelab->x(); - CTX::instance()->solverPosition[1] = onelab->y(); - CTX::instance()->solverSize[0] = onelab->w(); - CTX::instance()->solverSize[1] = onelab->h(); -#endif #if defined(HAVE_3M) storeWindowPosition3M(); #endif @@ -909,8 +862,6 @@ void window_cb(Fl_Widget *w, void *data) FlGui::instance()->manip->win->iconize(); if(FlGui::instance()->stats->win->shown()) FlGui::instance()->stats->win->iconize(); - if(FlGui::instance()->menu->win->shown()) - FlGui::instance()->menu->win->iconize(); } else if(str == "zoom"){ if(zoom){ @@ -936,7 +887,6 @@ void window_cb(Fl_Widget *w, void *data) #endif zoom = 1; } - FlGui::instance()->menu->win->show(); } else if(str == "front"){ // the order is important! @@ -952,10 +902,6 @@ void window_cb(Fl_Widget *w, void *data) FlGui::instance()->geoContext->win->show(); if(FlGui::instance()->meshContext->win->shown()) FlGui::instance()->meshContext->win->show(); -#if defined(HAVE_ONELAB) && (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3) - if(FlGui::instance()->onelab->shown()) - FlGui::instance()->onelab->show(); -#endif if(FlGui::instance()->visibility->win->shown()) FlGui::instance()->visibility->win->show(); if(FlGui::instance()->highordertools->win->shown()) @@ -966,7 +912,6 @@ void window_cb(Fl_Widget *w, void *data) FlGui::instance()->manip->win->show(); if(FlGui::instance()->stats->win->shown()) FlGui::instance()->stats->win->show(); - FlGui::instance()->menu->win->show(); } } @@ -986,3 +931,13 @@ void FlGui::saveMessages(const char *fileName) { FlGui::instance()->graph[0]->saveMessages(fileName); } + +void FlGui::rebuildTree() +{ + onelab->rebuildTree(); +} + +void FlGui::openModule(const std::string &name) +{ + onelab->openTreeItem("0Gmsh modules/" + name); +} diff --git a/Fltk/FlGui.h b/Fltk/FlGui.h index 5afbdb5873e79cd29a2805e145501396cd0c72de..d58b2135aec4d4f90711398f7e15cdbc255bdd9f 100644 --- a/Fltk/FlGui.h +++ b/Fltk/FlGui.h @@ -20,7 +20,6 @@ class graphicWindow; class openglWindow; -class menuWindow; class optionWindow; class fieldWindow; class pluginWindow; @@ -32,7 +31,7 @@ class manipWindow; class geometryContextWindow; class meshContextWindow; class aboutWindow; -class onelabWindow; +class onelabGroup; class Fl_Widget; class GVertex; @@ -53,7 +52,6 @@ class FlGui{ std::vector<MElement*> selectedElements; public: std::vector<graphicWindow*> graph; - menuWindow *menu; optionWindow *options; fieldWindow *fields; pluginWindow *plugins; @@ -65,7 +63,7 @@ class FlGui{ geometryContextWindow *geoContext; meshContextWindow *meshContext; aboutWindow *about; - onelabWindow *onelab; + onelabGroup *onelab; public: FlGui(int argc, char **argv); ~FlGui(){} @@ -107,7 +105,7 @@ class FlGui{ // select an entity in the most recent graphic window char selectEntity(int type); // display status message - void setStatus(const char *msg, int num); + void setStatus(const char *msg, bool opengl=false); // display status message and update progress bar void setProgress(const char *msg, double val, double min, double max); // create the window for physical context dependant definitions @@ -118,6 +116,10 @@ class FlGui{ void showMessages(); // add line in message console(s) void saveMessages(const char *fileName); + // rebuild the tree + void rebuildTree(); + // open module in tree + void openModule(const std::string &name); }; void redraw_cb(Fl_Widget *w, void *data); diff --git a/Fltk/classificationEditor.cpp b/Fltk/classificationEditor.cpp index f7607a3bd9adf0007edb9cbd4dab69f24d4b2070..c869db84d06c71287e3fe2b485249d2532556edb 100644 --- a/Fltk/classificationEditor.cpp +++ b/Fltk/classificationEditor.cpp @@ -20,7 +20,7 @@ #include "discreteEdge.h" #include "discreteFace.h" -extern GEdge *getNewModelEdge(GFace *gf1, GFace *gf2, +extern GEdge *getNewModelEdge(GFace *gf1, GFace *gf2, std::map<std::pair<int, int>, GEdge*> &newEdges); extern void recurClassifyEdges(MTri3 *t, std::map<MTriangle*, GFace*> &reverse, @@ -34,8 +34,8 @@ extern void recurClassify(MTri3 *t, GFace *gf, static void NoElementsSelectedMode(classificationEditor *e) { - e->buttons[CLASS_BUTTON_SELECT_ELEMENTS]->activate(); - e->buttons[CLASS_BUTTON_SELECT_ALL_ELEMENTS]->activate(); + e->buttons[CLASS_BUTTON_SELECT_ELEMENTS]->activate(); + e->buttons[CLASS_BUTTON_SELECT_ALL_ELEMENTS]->activate(); e->buttons[CLASS_BUTTON_DELETE_FROM_SELECTION]->deactivate(); e->buttons[CLASS_BUTTON_RESET_SELECTION]->deactivate(); @@ -45,8 +45,8 @@ static void NoElementsSelectedMode(classificationEditor *e) CTX::instance()->mesh.changed = ENT_ALL; CTX::instance()->pickElements = 0; - drawContext::global()->draw(); - Msg::StatusBar(3, false, ""); + drawContext::global()->draw(); + Msg::StatusGl(""); } static void ElementsSelectedMode(classificationEditor *e) @@ -56,14 +56,14 @@ static void ElementsSelectedMode(classificationEditor *e) e->toggles[CLASS_TOGGLE_BOUNDARY]->activate(); e->inputs[CLASS_VALUE_ANGLE]->activate(); - e->buttons[CLASS_BUTTON_SELECT_ELEMENTS]->deactivate(); - e->buttons[CLASS_BUTTON_SELECT_ALL_ELEMENTS]->deactivate(); + e->buttons[CLASS_BUTTON_SELECT_ELEMENTS]->deactivate(); + e->buttons[CLASS_BUTTON_SELECT_ALL_ELEMENTS]->deactivate(); } static void update_edges_cb(Fl_Widget *w, void *data) { classificationEditor *e = (classificationEditor*)data; - + if(!e->selected) return; for(unsigned int i = 0; i < e->selected->lines.size(); i++) @@ -75,20 +75,20 @@ static void update_edges_cb(Fl_Widget *w, void *data) edge_angle ea = e->edges_detected[i]; if(ea.angle <= threshold) break; e->selected->lines.push_back(new MLine(ea.v1, ea.v2)); - } + } if(e->toggles[CLASS_TOGGLE_BOUNDARY]->value()){ for(unsigned int i = 0 ; i < e->edges_lonly.size(); i++){ edge_angle ea = e->edges_lonly[i]; e->selected->lines.push_back(new MLine(ea.v1, ea.v2)); - } + } } Msg::Info("Edges: %d inside, %d boundary, %d selected", (int)e->edges_detected.size(), (int)e->edges_lonly.size(), (int)e->selected->lines.size()); - + CTX::instance()->mesh.changed = ENT_ALL; - drawContext::global()->draw(); + drawContext::global()->draw(); } static void select_elements_cb(Fl_Widget *w, void *data) @@ -104,11 +104,11 @@ static void select_elements_cb(Fl_Widget *w, void *data) } if(all){ - for(GModel::fiter it = GModel::current()->firstFace(); + for(GModel::fiter it = GModel::current()->firstFace(); it != GModel::current()->lastFace(); ++it){ - e->elements.insert(e->elements.end(), (*it)->triangles.begin(), + e->elements.insert(e->elements.end(), (*it)->triangles.begin(), (*it)->triangles.end()); - e->elements.insert(e->elements.end(), (*it)->quadrangles.begin(), + e->elements.insert(e->elements.end(), (*it)->quadrangles.begin(), (*it)->quadrangles.end()); } } @@ -117,15 +117,15 @@ static void select_elements_cb(Fl_Widget *w, void *data) while(1) { CTX::instance()->mesh.changed = ENT_ALL; drawContext::global()->draw(); - Msg::StatusBar(3, false, "Select elements\n" - "[Press 'e' to end selection or 'q' to abort]"); - + Msg::StatusGl("Select elements\n" + "[Press 'e' to end selection or 'q' to abort]"); + char ib = FlGui::instance()->selectEntity(ENT_ALL); if(ib == 'l') { for(unsigned int i = 0; i < FlGui::instance()->selectedElements.size(); i++){ MElement *me = FlGui::instance()->selectedElements[i]; if(me->getDim() == 2 && me->getVisibility() != 2){ - me->setVisibility(2); + me->setVisibility(2); e->elements.push_back(me); } } @@ -156,7 +156,7 @@ static void select_elements_cb(Fl_Widget *w, void *data) buildListOfEdgeAngle(adj, e->edges_detected, e->edges_lonly); ElementsSelectedMode(e); update_edges_cb(0, data); - Msg::StatusBar(3, false, ""); + Msg::StatusGl(""); } static void hide_cb(Fl_Widget *w, void *data) @@ -193,20 +193,20 @@ static void delete_edge_cb(Fl_Widget *w, void *data) CTX::instance()->pickElements = 1; std::vector<MLine*> ele; - + while(1) { CTX::instance()->mesh.changed = ENT_ALL; drawContext::global()->draw(); - Msg::StatusBar(3, false, "Select elements\n" - "[Press 'e' to end selection or 'q' to abort]"); - + Msg::StatusGl("Select elements\n" + "[Press 'e' to end selection or 'q' to abort]"); + char ib = FlGui::instance()->selectEntity(ENT_ALL); if(ib == 'l') { for(unsigned int i = 0; i < FlGui::instance()->selectedElements.size(); i++){ MElement *me = FlGui::instance()->selectedElements[i]; if(me->getType() == TYPE_LIN && me->getVisibility() != 2){ - me->setVisibility(2); + me->setVisibility(2); ele.push_back((MLine*)me); } } @@ -235,18 +235,18 @@ static void delete_edge_cb(Fl_Widget *w, void *data) // look in all selected edges if a deleted one is present and delete it std::vector<MLine*> temp = e->selected->lines; e->selected->lines.clear(); - for(unsigned int i = 0; i < temp.size(); i++){ + for(unsigned int i = 0; i < temp.size(); i++){ std::vector<MLine*>::iterator it = std::find(ele.begin(), ele.end(), temp[i]); - if(it != ele.end()) + if(it != ele.end()) delete temp[i]; else e->selected->lines.push_back(temp[i]); } - + CTX::instance()->mesh.changed = ENT_ALL; CTX::instance()->pickElements = 0; - drawContext::global()->draw(); - Msg::StatusBar(3, false, ""); + drawContext::global()->draw(); + Msg::StatusGl(""); e->elements.clear(); e->edges_detected.clear(); @@ -272,7 +272,7 @@ static void select_surfaces_cb(Fl_Widget *w, void *data) bool all = (w == e->buttons[CLASS_BUTTON_SELECT_ALL_SURFACES]); if(all){ - for(GModel::fiter it = GModel::current()->firstFace(); + for(GModel::fiter it = GModel::current()->firstFace(); it != GModel::current()->lastFace(); ++it) e->faces.insert(*it); } @@ -282,8 +282,8 @@ static void select_surfaces_cb(Fl_Widget *w, void *data) while(1) { CTX::instance()->mesh.changed = ENT_ALL; drawContext::global()->draw(); - Msg::StatusBar(3, false, "Select Surface\n" - "[Press 'e' to end selection or 'q' to abort]"); + Msg::StatusGl("Select Surface\n" + "[Press 'e' to end selection or 'q' to abort]"); char ib = FlGui::instance()->selectEntity(ENT_SURFACE); if(ib == 'l') { for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++){ @@ -308,17 +308,17 @@ static void select_surfaces_cb(Fl_Widget *w, void *data) e->buttons[CLASS_BUTTON_CLASSIFY]->activate(); CTX::instance()->mesh.changed = ENT_ALL; - drawContext::global()->draw(); - Msg::StatusBar(3, false, ""); + drawContext::global()->draw(); + Msg::StatusGl(""); } static void classify_cb(Fl_Widget *w, void *data) { classificationEditor *e = (classificationEditor*)data; std::map<MLine*, GEdge*, compareMLinePtr> lines; - for(GModel::eiter it = GModel::current()->firstEdge(); + for(GModel::eiter it = GModel::current()->firstEdge(); it != GModel::current()->lastEdge(); ++it){ - for(unsigned int i = 0; i < (*it)->lines.size();i++) + for(unsigned int i = 0; i < (*it)->lines.size();i++) lines[(*it)->lines[i]] = *it; } @@ -349,23 +349,23 @@ static void classify_cb(Fl_Widget *w, void *data) } ++it; } - + // color some lines it = tris.begin(); while(it != tris.end()){ (*it)->setDeleted(false); ++it; } - + it = tris.begin(); - + // classify edges that are bound by different GFaces std::map<std::pair<int, int>, GEdge*> newEdges; std::set<MLine*> touched; std::set<MTri3*> tritouched; recurClassifyEdges(*it, reverse, lines, touched, tritouched, newEdges); - - // check if new edges should not be splitted + + // check if new edges should not be splitted // splitted if composed of several open or closed edges for (std::map<std::pair<int, int>, GEdge*>::iterator it = newEdges.begin(); it != newEdges.end() ; ++it){ @@ -382,7 +382,7 @@ static void classify_cb(Fl_Widget *w, void *data) it++; for (int i = 0; i < 2; i++) { for (std::list<MLine*>::iterator it = segments.begin(); - it != segments.end(); ++it){ + it != segments.end(); ++it){ MVertex *v1 = (*it)->getVertex(0); MVertex *v2 = (*it)->getVertex(1); std::list<MLine*>::iterator itp; @@ -422,7 +422,7 @@ static void classify_cb(Fl_Widget *w, void *data) GEdge *ge = it->second; GModel::current()->remove(ge); } - + while(it != tris.end()){ delete *it; ++it; @@ -452,13 +452,13 @@ classificationEditor::classificationEditor() : selected(0) window = new paletteWindow (width, height, CTX::instance()->nonModalWindows ? true : false, "Reclassify 2D"); window->box(GMSH_WINDOW_BOX); - + int x = WB, y = WB; { Fl_Box *b = new Fl_Box (x, y, width, BH, "1. Select mesh elements on which to perform edge detection"); b->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE); - + x += WB; y += BH; buttons[CLASS_BUTTON_SELECT_ELEMENTS] = new Fl_Button @@ -468,13 +468,13 @@ classificationEditor::classificationEditor() : selected(0) buttons[CLASS_BUTTON_SELECT_ALL_ELEMENTS] = new Fl_Button (x + BBB + WB, y, (int)(0.5 * BBB) - WB, BH, "All"); buttons[CLASS_BUTTON_SELECT_ALL_ELEMENTS]->callback(select_elements_cb, this); - + toggles[CLASS_TOGGLE_HIDE] = new Fl_Check_Button - ((int)(x + 1.5 * BBB + WB), y, (int)(width - 1.5 * BBB - x - 2 * WB), BH, + ((int)(x + 1.5 * BBB + WB), y, (int)(width - 1.5 * BBB - x - 2 * WB), BH, "Hide unselected elements"); toggles[CLASS_TOGGLE_HIDE]->type(FL_TOGGLE_BUTTON); toggles[CLASS_TOGGLE_HIDE]->callback(hide_cb, this); - + x -= WB; } { @@ -488,7 +488,7 @@ classificationEditor::classificationEditor() : selected(0) Fl_Box *b = new Fl_Box (x, y, width, BH, "2. Fine-tune edge selection"); b->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE); - + x += WB; y += BH; inputs[CLASS_VALUE_ANGLE] = new Fl_Value_Input @@ -498,7 +498,7 @@ classificationEditor::classificationEditor() : selected(0) inputs[CLASS_VALUE_ANGLE]->minimum(0); inputs[CLASS_VALUE_ANGLE]->align(FL_ALIGN_RIGHT); inputs[CLASS_VALUE_ANGLE]->step(1); - inputs[CLASS_VALUE_ANGLE]->when(FL_WHEN_RELEASE); + inputs[CLASS_VALUE_ANGLE]->when(FL_WHEN_RELEASE); inputs[CLASS_VALUE_ANGLE]->callback(update_edges_cb, this); toggles[CLASS_TOGGLE_SHOW_ONLY_EDGES] = new Fl_Check_Button @@ -506,24 +506,24 @@ classificationEditor::classificationEditor() : selected(0) "Show only edges"); toggles[CLASS_TOGGLE_SHOW_ONLY_EDGES]->type(FL_TOGGLE_BUTTON); toggles[CLASS_TOGGLE_SHOW_ONLY_EDGES]->callback(show_only_edges_cb, this); - + y += BH; toggles[CLASS_TOGGLE_BOUNDARY] = new Fl_Check_Button (x, y, width - x - 2 * WB, BH, "Include edges on boundary (closure)"); toggles[CLASS_TOGGLE_BOUNDARY]->type(FL_TOGGLE_BUTTON); toggles[CLASS_TOGGLE_BOUNDARY]->callback(update_edges_cb, this); - + y += BH; - buttons[CLASS_BUTTON_DELETE_FROM_SELECTION] = new Fl_Button + buttons[CLASS_BUTTON_DELETE_FROM_SELECTION] = new Fl_Button (x, y, (int)(1.5 * BBB), BH, "Delete edges from selection"); - buttons[CLASS_BUTTON_DELETE_FROM_SELECTION]->callback(delete_edge_cb, this); + buttons[CLASS_BUTTON_DELETE_FROM_SELECTION]->callback(delete_edge_cb, this); buttons[CLASS_BUTTON_DELETE_FROM_SELECTION]->deactivate(); - - buttons[CLASS_BUTTON_RESET_SELECTION] = new Fl_Button + + buttons[CLASS_BUTTON_RESET_SELECTION] = new Fl_Button (x + (int)(1.5 * BBB + WB), y, BBB, BH, "Reset selection"); - buttons[CLASS_BUTTON_RESET_SELECTION]->callback(reset_selection_cb, this); + buttons[CLASS_BUTTON_RESET_SELECTION]->callback(reset_selection_cb, this); buttons[CLASS_BUTTON_RESET_SELECTION]->deactivate(); - + x -= WB; } { @@ -537,7 +537,7 @@ classificationEditor::classificationEditor() : selected(0) Fl_Box *b = new Fl_Box (x, y, width, BH, "3. Reclassify surfaces using selected edges"); b->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE); - + x += WB; y += BH; @@ -549,7 +549,7 @@ classificationEditor::classificationEditor() : selected(0) (x + BBB + WB, y, (int)(0.5 * BBB) - WB, BH, "All"); buttons[CLASS_BUTTON_SELECT_ALL_SURFACES]->callback(select_surfaces_cb, this); - buttons[CLASS_BUTTON_CLASSIFY] = new Fl_Return_Button + buttons[CLASS_BUTTON_CLASSIFY] = new Fl_Return_Button ((int)(x + 1.5 * BBB + WB), y, BBB, BH, "Reclassify"); buttons[CLASS_BUTTON_CLASSIFY]->callback(classify_cb, this); buttons[CLASS_BUTTON_CLASSIFY]->deactivate(); diff --git a/Fltk/fileDialogs.cpp b/Fltk/fileDialogs.cpp index f41eb646171200d9be930cab587e5d5056c6782c..c5a51abbbb1fcd6972a7c9aaeee10ad617d3e800 100644 --- a/Fltk/fileDialogs.cpp +++ b/Fltk/fileDialogs.cpp @@ -701,9 +701,9 @@ int optionsFileDialog(const char *name) Fl_Widget* o = Fl::readqueue(); if (!o) break; if (o == dialog->ok) { - Msg::StatusBar(2, true, "Writing '%s'...", name); + Msg::StatusBar(true, "Writing '%s'...", name); PrintOptions(0, GMSH_FULLRC, dialog->b[0]->value(), dialog->b[1]->value(), name); - Msg::StatusBar(2, true, "Done writing '%s'", name); + Msg::StatusBar(true, "Done writing '%s'", name); dialog->window->hide(); return 1; } diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp index 311a3721e63fdc0a3bc16a1733c786239de13360..9cc68a765d9fd7d9f1cd1f2321e6719b8e4c3b2b 100644 --- a/Fltk/graphicWindow.cpp +++ b/Fltk/graphicWindow.cpp @@ -3,23 +3,2164 @@ // See the LICENSE.txt file for license information. Please report all // bugs and problems to <gmsh@geuz.org>. +#include "GmshConfig.h" +#include "GmshDefines.h" +#if !defined(HAVE_NO_STDINT_H) +#include <stdint.h> +#elif defined(HAVE_NO_INTPTR_T) +typedef unsigned long intptr_t; +#endif #include <string.h> -#include <FL/fl_draw.H> +#include <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <FL/Fl_Box.H> #include <FL/fl_ask.H> +#include <FL/filename.H> +#include <FL/fl_draw.H> +#include <FL/Fl_Tree.H> #include "FlGui.h" -#include "graphicWindow.h" -#include "paletteWindow.h" #include "mainWindow.h" -#include "menuWindow.h" +#include "paletteWindow.h" +#include "graphicWindow.h" +#include "optionWindow.h" +#include "statisticsWindow.h" +#include "contextWindow.h" +#include "visibilityWindow.h" +#include "highOrderToolsWindow.h" +#include "clippingWindow.h" #include "manipWindow.h" -#include "extraDialogs.h" +#include "fieldWindow.h" +#include "pluginWindow.h" +#include "aboutWindow.h" +#include "onelabGroup.h" #include "fileDialogs.h" +#include "extraDialogs.h" +#include "partitionDialog.h" +#include "projectionEditor.h" +#include "classificationEditor.h" +#include "GModel.h" #include "PView.h" #include "PViewData.h" -#include "OS.h" +#include "PViewOptions.h" #include "OpenFile.h" +#include "CreateFile.h" +#include "findLinks.h" +#include "GeoStringInterface.h" +#include "CommandLine.h" #include "Options.h" #include "Context.h" +#include "StringUtils.h" +#include "Generator.h" +#include "HighOrder.h" +#include "OS.h" +#if defined(HAVE_3M) +#include "3M.h" +#endif + +static void file_new_cb(Fl_Widget *w, void *data) +{ + test: + if(fileChooser(FILE_CHOOSER_CREATE, "New", "", + GModel::current()->getFileName().c_str())) { + std::string name = fileChooserGetName(1); + if(!StatFile(name)){ + if(fl_choice("File '%s' already exists.\n\nDo you want to erase it?", + "Cancel", "Erase", 0, name.c_str())) + UnlinkFile(name); + else + goto test; + } + FILE *fp = fopen(name.c_str(), "w"); + if(!fp){ + Msg::Error("Unable to open file '%s'", name.c_str()); + return; + } + time_t now; + time(&now); + fprintf(fp, "// Gmsh project created on %s", ctime(&now)); + fclose(fp); + OpenProject(name); + drawContext::global()->draw(); + } +} + +#if defined(HAVE_NATIVE_FILE_CHOOSER) +# define TT "\t" +# define NN "\n" +#else +# define TT " (" +# define NN ")\t" +#endif + +static const char *input_formats = + "All Files" TT "*.*" NN + "Geometry - Gmsh GEO" TT "*.geo" NN +#if defined(HAVE_ACIS) + "Geometry - ACIS" TT "*.sat" NN +#endif +#if defined(HAVE_OCC) + "Geometry - OpenCASCADE BRep" TT "*.brep" NN + "Geometry - OpenCASCADE IGES" TT "*.{igs,iges}" NN + "Geometry - OpenCASCADE STEP" TT "*.{stp,step}" NN +#endif + "Mesh - Gmsh MSH" TT "*.msh" NN + "Mesh - Diffpack 3D" TT "*.diff" NN + "Mesh - I-deas Universal" TT "*.unv" NN +#if defined(HAVE_MED) + "Mesh - MED" TT "*.{med,mmed}" NN +#endif + "Mesh - INRIA Medit" TT "*.mesh" NN + "Mesh - Nastran Bulk Data File" TT "*.{bdf,nas}" NN + "Mesh - Plot3D Structured Mesh" TT "*.p3d" NN + "Mesh - STL Surface" TT "*.stl" NN + "Mesh - VTK" TT "*.vtk" NN + "Mesh - VRML Surface" TT "*.{wrl,vrml}" NN + "Mesh - PLY2 Surface" TT "*.ply2" NN + "Post-processing - Gmsh POS" TT "*.pos" NN +#if defined(HAVE_MED) + "Post-processing - MED" TT "*.{rmed}" NN +#endif + "Image - BMP" TT "*.bmp" NN +#if defined(HAVE_LIBJPEG) + "Image - JPEG" TT "*.{jpg,jpeg}" NN +#endif + "Image - PBM" TT "*.pbm" NN + "Image - PGM" TT "*.pgm" NN +#if defined(HAVE_LIBPNG) + "Image - PNG" TT "*.png" NN +#endif + "Image - PNM" TT "*.pnm" NN + "Image - PPM" TT "*.ppm" NN; + +static void file_open_cb(Fl_Widget *w, void *data) +{ + int n = PView::list.size(); + if(fileChooser(FILE_CHOOSER_SINGLE, "Open", input_formats, + GModel::current()->getFileName().c_str())) { + OpenProject(fileChooserGetName(1)); + drawContext::global()->draw(); + } + if(n != (int)PView::list.size()) + FlGui::instance()->openModule("Post-processing"); + if(CTX::instance()->launchSolverAtStartup >= 0) + solver_cb(0, (void*)CTX::instance()->launchSolverAtStartup); +} + +static void file_merge_cb(Fl_Widget *w, void *data) +{ + int n = PView::list.size(); + int f = fileChooser(FILE_CHOOSER_MULTI, "Merge", input_formats, + GModel::current()->getFileName().c_str()); + if(f) { + for(int i = 1; i <= f; i++) + MergeFile(fileChooserGetName(i)); + drawContext::global()->draw(); + } + if(n != (int)PView::list.size()) + FlGui::instance()->openModule("Post-processing"); + if(CTX::instance()->launchSolverAtStartup >= 0) + solver_cb(0, (void*)CTX::instance()->launchSolverAtStartup); +} + +static void file_open_recent_cb(Fl_Widget *w, void *data) +{ + if(!data) return; + std::string str((const char*)data); + int n = PView::list.size(); + OpenProject(str); + drawContext::global()->draw(); + if(n != (int)PView::list.size()) + FlGui::instance()->openModule("Post-processing"); + if(CTX::instance()->launchSolverAtStartup >= 0) + solver_cb(0, (void*)CTX::instance()->launchSolverAtStartup); +} + +static void file_clear_cb(Fl_Widget *w, void *data) +{ + ClearProject(); + drawContext::global()->draw(); +} + +static void file_remote_cb(Fl_Widget *w, void *data) +{ + onelab::localNetworkClient *c; + onelab::server::citer it = onelab::server::instance()->findClient("GmshRemote"); + if(it == onelab::server::instance()->lastClient()){ + c = new onelab::localNetworkClient("GmshRemote", ""); + c->setSocketSwitch("-socket"); + } + else + c = (onelab::localNetworkClient*)it->second; + GmshServer *server = c->getGmshServer(); + + std::string str((const char*)data); + + if(str == "start"){ + if(server){ + Msg::Error("Cannot start: remote Gmsh is already running"); + return; + } + c->setExecutable(connectionChooser()); + if(c->getExecutable().size()) c->run(); + } + else{ + if(!server){ + Msg::Error("Cannot %s: remote Gmsh not running", str.c_str()); + return; + } + if(str == "stop"){ + server->SendString(GmshSocket::GMSH_STOP, "Disconnect!"); + } + else if(str == "merge"){ + const char *file = fl_input("Merge", "/tmp/data.pos"); + if(file) server->SendString(GmshSocket::GMSH_MERGE_FILE, file); + } + else if(str == "clear"){ + server->SendString(GmshSocket::GMSH_PARSE_STRING, "Delete All;"); + for(int i = PView::list.size() - 1; i >= 0; i--) + if(PView::list[i]->getData()->isRemote()) delete PView::list[i]; + FlGui::instance()->updateViews(); + drawContext::global()->draw(); + } + else if(str == "test"){ + server->SendString(GmshSocket::GMSH_SPEED_TEST, "Speed test"); + } + } +} + +static void file_window_cb(Fl_Widget *w, void *data) +{ + std::string str((const char*)data); + if(str == "new"){ + graphicWindow *g1 = FlGui::instance()->graph.back(); + graphicWindow *g2 = new graphicWindow(false, CTX::instance()->numTiles); + FlGui::instance()->graph.push_back(g2); + FlGui::instance()->setGraphicTitle(GModel::current()->getFileName()); + g2->win->resize(g1->win->x() + 10, g1->win->y() + 10, + g1->win->w(), g1->win->h()); + g2->win->show(); + } + else if(str == "split_h"){ + FlGui::instance()->splitCurrentOpenglWindow('h'); + } + else if(str == "split_v"){ + FlGui::instance()->splitCurrentOpenglWindow('v'); + } + else if(str == "split_u"){ + FlGui::instance()->splitCurrentOpenglWindow('u'); + } + drawContext::global()->draw(); +} + +static int _save_msh(const char *name){ return mshFileDialog(name); } +static int _save_mesh_stat(const char *name){ return meshStatFileDialog(name); } +static int _save_options(const char *name){ return optionsFileDialog(name); } +static int _save_geo(const char *name){ return geoFileDialog(name); } +static int _save_brep(const char *name){ CreateOutputFile(name, FORMAT_BREP); return 1; } +static int _save_step(const char *name){ CreateOutputFile(name, FORMAT_STEP); return 1; } +static int _save_cgns(const char *name){ return cgnsFileDialog(name); } +static int _save_unv(const char *name){ return unvFileDialog(name); } +static int _save_vtk(const char *name){ return genericMeshFileDialog + (name, "VTK Options", FORMAT_VTK, true, false); } +static int _save_diff(const char *name){ return genericMeshFileDialog + (name, "Diffpack Options", FORMAT_DIFF, true, false); } +static int _save_inp(const char *name){ return genericMeshFileDialog + (name, "Abaqus INP Options", FORMAT_INP, false, false); } +static int _save_med(const char *name){ return genericMeshFileDialog + (name, "MED Options", FORMAT_MED, false, false); } +static int _save_mesh(const char *name){ return genericMeshFileDialog + (name, "MESH Options", FORMAT_MESH, false, true); } +static int _save_mail(const char *name){ return genericMeshFileDialog + (name, "MAIL Options", FORMAT_MAIL, false, false); } +static int _save_bdf(const char *name){ return bdfFileDialog(name); } +static int _save_p3d(const char *name){ return genericMeshFileDialog + (name, "P3D Options", FORMAT_P3D, false, false); } +static int _save_ir3(const char *name){ return genericMeshFileDialog + (name, "Iridium Options", FORMAT_IR3, false, true); } +static int _save_stl(const char *name){ return genericMeshFileDialog + (name, "STL Options", FORMAT_STL, true, false); } +static int _save_vrml(const char *name){ return genericMeshFileDialog + (name, "VRML Options", FORMAT_VRML, false, false); } +static int _save_ply2(const char *name){ return genericMeshFileDialog + (name, "PLY2 Options", FORMAT_PLY2, false, false); } +static int _save_eps(const char *name){ return gl2psFileDialog + (name, "EPS Options", FORMAT_EPS); } +static int _save_gif(const char *name){ return gifFileDialog(name); } +static int _save_jpeg(const char *name){ return jpegFileDialog(name); } +static int _save_mpeg(const char *name){ return mpegFileDialog(name); } +static int _save_tex(const char *name){ return latexFileDialog(name); } +static int _save_pdf(const char *name){ return gl2psFileDialog + (name, "PDF Options", FORMAT_PDF); } +static int _save_png(const char *name){ return genericBitmapFileDialog + (name, "PNG Options", FORMAT_PNG); } +static int _save_ps(const char *name){ return gl2psFileDialog + (name, "PS Options", FORMAT_PS); } +static int _save_ppm(const char *name){ return genericBitmapFileDialog + (name, "PPM Options", FORMAT_PPM); } +static int _save_svg(const char *name){ return gl2psFileDialog + (name, "SVG Options", FORMAT_SVG); } +static int _save_yuv(const char *name){ return genericBitmapFileDialog + (name, "YUV Options", FORMAT_YUV); } +static int _save_view_pos(const char *name){ return posFileDialog(name); } +static int _save_view_med(const char *name){ return genericViewFileDialog + (name, "MED Options", 6); } +static int _save_view_txt(const char *name){ return genericViewFileDialog + (name, "TXT Options", 4); } + +static int _save_auto(const char *name) +{ + switch(GuessFileFormatFromFileName(name)){ + case FORMAT_MSH : return _save_msh(name); + case FORMAT_POS : return _save_view_pos(name); + case FORMAT_TXT : return _save_view_txt(name); + case FORMAT_OPT : return _save_options(name); + case FORMAT_GEO : return _save_geo(name); + case FORMAT_BREP : return _save_brep(name); + case FORMAT_STEP : return _save_step(name); + case FORMAT_CGNS : return _save_cgns(name); + case FORMAT_UNV : return _save_unv(name); + case FORMAT_VTK : return _save_vtk(name); + case FORMAT_MED : return _save_med(name); + case FORMAT_RMED : return _save_view_med(name); + case FORMAT_MESH : return _save_mesh(name); + case FORMAT_MAIL : return _save_mail(name); + case FORMAT_BDF : return _save_bdf(name); + case FORMAT_DIFF : return _save_diff(name); + case FORMAT_INP : return _save_inp(name); + case FORMAT_P3D : return _save_p3d(name); + case FORMAT_IR3 : return _save_ir3(name); + case FORMAT_STL : return _save_stl(name); + case FORMAT_VRML : return _save_vrml(name); + case FORMAT_PLY2 : return _save_ply2(name); + case FORMAT_EPS : return _save_eps(name); + case FORMAT_GIF : return _save_gif(name); + case FORMAT_JPEG : return _save_jpeg(name); + case FORMAT_MPEG : return _save_mpeg(name); + case FORMAT_TEX : return _save_tex(name); + case FORMAT_PDF : return _save_pdf(name); + case FORMAT_PNG : return _save_png(name); + case FORMAT_PS : return _save_ps(name); + case FORMAT_PPM : return _save_ppm(name); + case FORMAT_SVG : return _save_svg(name); + case FORMAT_YUV : return _save_yuv(name); + default : + CreateOutputFile(name, FORMAT_AUTO); + return 1; + } +} + +typedef struct{ + const char *pat; + int (*func) (const char *name); +} patXfunc; + +static void file_save_as_cb(Fl_Widget *w, void *data) +{ + static patXfunc formats[] = { + {"Guess From Extension" TT "*.*", _save_auto}, + {"Geometry - Gmsh Options" TT "*.opt", _save_options}, + {"Geometry - Gmsh Unrolled GEO" TT "*.geo", _save_geo}, +#if defined(HAVE_OCC) + {"Geometry - OpenCASCADE STEP" TT "*.step", _save_step}, + {"Geometry - OpenCASCADE BRep" TT "*.brep", _save_brep}, +#endif + {"Mesh - Gmsh MSH" TT "*.msh", _save_msh}, + {"Mesh - Abaqus INP" TT "*.inp", _save_inp}, +#if defined(HAVE_LIBCGNS) + {"Mesh - CGNS (Experimental)" TT "*.cgns", _save_cgns}, +#endif + {"Mesh - Diffpack 3D" TT "*.diff", _save_diff}, + {"Mesh - I-deas Universal" TT "*.unv", _save_unv}, + {"Mesh - Iridum" TT "*.ir3", _save_ir3}, +#if defined(HAVE_MED) + {"Mesh - MED" TT "*.med", _save_med}, +#endif + {"Mesh - INRIA Medit" TT "*.mesh", _save_mesh}, + {"Mesh - CEA Triangulation" TT "*.mail", _save_mail}, + {"Mesh - Nastran Bulk Data File" TT "*.bdf", _save_bdf}, + {"Mesh - Plot3D Structured Mesh" TT "*.p3d", _save_p3d}, + {"Mesh - STL Surface" TT "*.stl", _save_stl}, + {"Mesh - VRML Surface" TT "*.wrl", _save_vrml}, + {"Mesh - VTK" TT "*.vtk", _save_vtk}, + {"Mesh - PLY2 Surface" TT "*.ply2", _save_ply2}, + {"Post-processing - Gmsh POS" TT "*.pos", _save_view_pos}, +#if defined(HAVE_MED) + {"Post-processing - MED" TT "*.rmed", _save_view_med}, +#endif + {"Post-processing - Generic TXT" TT "*.txt", _save_view_txt}, + {"Post-processing - Mesh Statistics" TT "*.pos", _save_mesh_stat}, + {"Image - Encapsulated PostScript" TT "*.eps", _save_eps}, + {"Image - GIF" TT "*.gif", _save_gif}, +#if defined(HAVE_LIBJPEG) + {"Image - JPEG" TT "*.jpg", _save_jpeg}, +#endif + {"Image - LaTeX" TT "*.tex", _save_tex}, + {"Image - PDF" TT "*.pdf", _save_pdf}, +#if defined(HAVE_LIBPNG) + {"Image - PNG" TT "*.png", _save_png}, +#endif + {"Image - PostScript" TT "*.ps", _save_ps}, + {"Image - PPM" TT "*.ppm", _save_ppm}, + {"Image - SVG" TT "*.svg", _save_svg}, + {"Image - YUV" TT "*.yuv", _save_yuv}, +#if defined(HAVE_MPEG_ENCODE) + {"Movie - MPEG" TT "*.mpg", _save_mpeg}, +#endif + }; + int nbformats = sizeof(formats) / sizeof(formats[0]); + static char *pat = 0; + if(!pat) { + pat = new char[nbformats * 256]; + strcpy(pat, formats[0].pat); + for(int i = 1; i < nbformats; i++) { + strcat(pat, NN); + strcat(pat, formats[i].pat); + } + } + + test: + if(fileChooser(FILE_CHOOSER_CREATE, "Save As", pat, + GModel::current()->getFileName().c_str())) { + std::string name = fileChooserGetName(1); + if(CTX::instance()->confirmOverwrite) { + if(!StatFile(name)) + if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", + "Cancel", "Replace", 0, name.c_str())) + goto test; + } + int i = fileChooserGetFilter(); + if(i >= 0 && i < nbformats){ + if(!formats[i].func(name.c_str())) goto test; + } + else{ // handle any additional automatic fltk filter + if(!_save_auto(name.c_str())) goto test; + } + } +} + +#undef TT +#undef NN + +static void file_options_save_cb(Fl_Widget *w, void *data) +{ + std::string str((const char*)data), fileName; + if(str == "file") + fileName = GModel::current()->getFileName() + ".opt"; + else + fileName = CTX::instance()->homeDir + CTX::instance()->optionsFileName; + Msg::StatusBar(true, "Writing '%s'...", fileName.c_str()); + if(str == "file") + PrintOptions(0, GMSH_FULLRC, 1, 0, fileName.c_str()); + else + PrintOptions(0, GMSH_OPTIONSRC, 1, 1, fileName.c_str()); + Msg::StatusBar(true, "Done writing '%s'", fileName.c_str()); +} + +static void file_rename_cb(Fl_Widget *w, void *data) +{ + test: + if(fileChooser(FILE_CHOOSER_CREATE, "Rename", "", + GModel::current()->getFileName().c_str())) { + std::string name = fileChooserGetName(1); + if(CTX::instance()->confirmOverwrite) { + if(!StatFile(name)) + if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", + "Cancel", "Replace", 0, name.c_str())) + goto test; + } + rename(GModel::current()->getFileName().c_str(), name.c_str()); + GModel::current()->setFileName(name); + GModel::current()->setName(SplitFileName(name)[1]); + FlGui::instance()->setGraphicTitle(GModel::current()->getFileName()); + drawContext::global()->draw(); + } +} + +void file_quit_cb(Fl_Widget *w, void *data) +{ + Msg::Exit(0); +} + +void file_watch_cb(Fl_Widget *w, void *data) +{ + if(w) CTX::instance()->watchFilePattern = patternChooser(); + + if(CTX::instance()->watchFilePattern.empty()) return; + + std::string pattern = FixRelativePath + (GModel::current()->getFileName(), CTX::instance()->watchFilePattern); + std::string directory = SplitFileName(pattern)[0]; + if(directory.empty()) directory = "./"; + + dirent **files = 0; + int num = fl_filename_list(directory.c_str(), &files, fl_numericsort); + if(num <= 0) return; + std::vector<std::string> matches; + for (int i = 0; i < num; i++) { + std::string name = directory + files[i]->d_name; + if(fl_filename_match(name.c_str(), pattern.c_str())) + matches.push_back(name); + free((void*)files[i]); + } + if(files) free((void*)files); + + Msg::Info("%d match%s for pattern '%s'", (int)matches.size(), + (matches.size() > 1) ? "es" : "", pattern.c_str()); + + std::set<std::string> allFiles; + for(unsigned int i = 0; i < GModel::list.size(); i++) + allFiles.insert(GetFileNameWithoutPath(GModel::list[i]->getFileName())); + for(unsigned int i = 0; i < PView::list.size(); i++) + for(int j = 0; j < PView::list[i]->getData()->getNumTimeSteps(); j++) + allFiles.insert(GetFileNameWithoutPath(PView::list[i]->getData()->getFileName(j))); + + for(unsigned int i = 0; i < matches.size(); i++) + if(allFiles.find(GetFileNameWithoutPath(matches[i])) == allFiles.end()) + MergeFile(matches[i]); + drawContext::global()->draw(); +} + +#if defined(__APPLE__) +# define CC(str) "Cmd+" str " " +#else +# define CC(str) "Ctrl+" str +#endif + +static void help_short_cb(Fl_Widget *w, void *data) +{ + Msg::Direct(" "); + Msg::Direct("Keyboard shortcuts:"); + Msg::Direct(" "); + Msg::Direct(" Left arrow Go to previous time step"); + Msg::Direct(" Right arrow Go to next time step"); + Msg::Direct(" Up arrow Make previous view visible"); + Msg::Direct(" Down arrow Make next view visible"); + Msg::Direct(" "); + Msg::Direct(" < Go back to previous context"); + Msg::Direct(" > Go forward to next context"); + Msg::Direct(" 0 Reload project file"); + Msg::Direct(" 1 or F1 Mesh lines"); + Msg::Direct(" 2 or F2 Mesh surfaces"); + Msg::Direct(" 3 or F3 Mesh volumes"); + Msg::Direct(" Escape Cancel lasso zoom/selection, toggle mouse selection ON/OFF"); + Msg::Direct(" "); + Msg::Direct(" g Go to geometry module"); + Msg::Direct(" m Go to mesh module"); + Msg::Direct(" p Go to post-processing module"); + Msg::Direct(" s Go to solver module"); + Msg::Direct(" "); + Msg::Direct(" Shift+a Bring all windows to front"); + Msg::Direct(" Shift+g Show geometry options"); + Msg::Direct(" Shift+m Show mesh options"); + Msg::Direct(" Shift+o Show general options"); + Msg::Direct(" Shift+p Show post-processing options"); + Msg::Direct(" Shift+s Show solver options"); + Msg::Direct(" Shift+u Show post-processing view plugins"); + Msg::Direct(" Shift+w Show post-processing view options"); + Msg::Direct(" Shift+Escape Enable full mouse selection"); + Msg::Direct(" "); + Msg::Direct(" " CC("i") " Show statistics window"); + Msg::Direct(" " CC("l") " Show message console"); +#if defined(__APPLE__) + Msg::Direct(" " CC("m") " Minimize window"); +#endif + Msg::Direct(" " CC("n") " Create new project file"); + Msg::Direct(" " CC("o") " Open project file"); + Msg::Direct(" " CC("q") " Quit"); + Msg::Direct(" " CC("r") " Rename project file"); + Msg::Direct(" " CC("s") " Save file as"); + Msg::Direct(" "); + Msg::Direct(" Shift+" CC("c") " Show clipping plane window"); + Msg::Direct(" Shift+" CC("m") " Show manipulator window"); + Msg::Direct(" Shift+" CC("n") " Show option window"); + Msg::Direct(" Shift+" CC("o") " Merge file(s)"); + Msg::Direct(" Shift+" CC("s") " Save mesh in default format"); + Msg::Direct(" Shift+" CC("u") " Show plugin window"); + Msg::Direct(" Shift+" CC("v") " Show visibility window"); + Msg::Direct(" "); + Msg::Direct(" Alt+a Loop through axes modes"); + Msg::Direct(" Alt+b Hide/show bounding boxes"); + Msg::Direct(" Alt+c Loop through predefined color schemes"); + Msg::Direct(" Alt+e Hide/Show element outlines for visible post-pro views"); + Msg::Direct(" Alt+f Change redraw mode (fast/full)"); + Msg::Direct(" Alt+h Hide/show all post-processing views"); + Msg::Direct(" Alt+i Hide/show all post-processing view scales"); + Msg::Direct(" Alt+l Hide/show geometry lines"); + Msg::Direct(" Alt+m Toggle visibility of all mesh entities"); + Msg::Direct(" Alt+n Hide/show all post-processing view annotations"); + Msg::Direct(" Alt+o Change projection mode (orthographic/perspective)"); + Msg::Direct(" Alt+p Hide/show geometry points"); + Msg::Direct(" Alt+r Loop through range modes for visible post-pro views"); + Msg::Direct(" Alt+s Hide/show geometry surfaces"); + Msg::Direct(" Alt+t Loop through interval modes for visible post-pro views"); + Msg::Direct(" Alt+v Hide/show geometry volumes"); + Msg::Direct(" Alt+w Enable/disable all lighting"); + Msg::Direct(" Alt+x Set X view"); + Msg::Direct(" Alt+y Set Y view"); + Msg::Direct(" Alt+z Set Z view"); + Msg::Direct(" "); + Msg::Direct(" Alt+Shift+a Hide/show small axes"); + Msg::Direct(" Alt+Shift+b Hide/show mesh volume faces"); + Msg::Direct(" Alt+Shift+d Hide/show mesh surface faces"); + Msg::Direct(" Alt+Shift+l Hide/show mesh lines"); + Msg::Direct(" Alt+Shift+o Adjust projection parameters"); + Msg::Direct(" Alt+Shift+p Hide/show mesh points"); + Msg::Direct(" Alt+Shift+s Hide/show mesh surface edges"); + Msg::Direct(" Alt+Shift+v Hide/show mesh volume edges"); + Msg::Direct(" Alt+Shift+w Reverse all mesh normals"); + Msg::Direct(" Alt+Shift+x Set -X view"); + Msg::Direct(" Alt+Shift+y Set -Y view"); + Msg::Direct(" Alt+Shift+z Set -Z view"); + Msg::Direct(" "); + FlGui::instance()->showMessages(); +} + +#undef CC + +static void help_mouse_cb(Fl_Widget *w, void *data) +{ + Msg::Direct(" "); + Msg::Direct("Mouse actions:"); + Msg::Direct(" "); + Msg::Direct(" Move - Highlight the entity under the mouse pointer"); + Msg::Direct(" and display its properties in the status bar"); + Msg::Direct(" - Resize a lasso zoom or a lasso (un)selection"); + Msg::Direct(" Left button - Rotate"); + Msg::Direct(" - Select an entity"); + Msg::Direct(" - Accept a lasso zoom or a lasso selection"); + Msg::Direct(" Ctrl+Left button Start a lasso zoom or a lasso (un)selection"); + Msg::Direct(" Middle button - Zoom"); + Msg::Direct(" - Unselect an entity"); + Msg::Direct(" - Accept a lasso zoom or a lasso unselection"); + Msg::Direct(" Ctrl+Middle button Orthogonalize display"); + Msg::Direct(" Right button - Pan"); + Msg::Direct(" - Cancel a lasso zoom or a lasso (un)selection"); + Msg::Direct(" - Pop-up menu on post-processing view button"); + Msg::Direct(" Ctrl+Right button Reset to default viewpoint"); + Msg::Direct(" "); + Msg::Direct(" For a 2 button mouse, Middle button = Shift+Left button"); + Msg::Direct(" For a 1 button mouse, Middle button = Shift+Left button, " + "Right button = Alt+Left button"); + Msg::Direct(" "); + FlGui::instance()->showMessages(); +} + +static void help_command_line_cb(Fl_Widget *w, void *data) +{ + Msg::Direct(" "); + PrintUsage("gmsh"); + FlGui::instance()->showMessages(); +} + +static void help_online_cb(Fl_Widget *w, void *data) +{ + std::string prog = FixWindowsPath(CTX::instance()->webBrowser); + SystemCall(ReplaceSubString("%s", "http://geuz.org/gmsh/doc/texinfo/", prog)); +} + +void help_about_cb(Fl_Widget *w, void *data) +{ + FlGui::instance()->about->win->show(); +} + +static void geometry_edit_cb(Fl_Widget *w, void *data) +{ + std::string prog = FixWindowsPath(CTX::instance()->editor); + std::string file = FixWindowsPath(GModel::current()->getFileName()); + SystemCall(ReplaceSubString("%s", file, prog)); +} + +void geometry_reload_cb(Fl_Widget *w, void *data) +{ + std::string fileName = GModel::current()->getFileName(); + OpenProject(fileName); + drawContext::global()->draw(); +} + +static void add_new_point() +{ + opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); + drawContext::global()->draw(); + + FlGui::instance()->geoContext->show(1); + + while(1) { + for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++) + for(unsigned int j = 0; j < FlGui::instance()->graph[i]->gl.size(); j++) + FlGui::instance()->graph[i]->gl[j]->addPointMode = true; + Msg::StatusGl("Move mouse and/or enter coordinates\n" + "[Press 'Shift' to hold position, 'e' to add point " + "or 'q' to abort]"); + char ib = FlGui::instance()->selectEntity(ENT_NONE); + if(ib == 'e'){ + add_point(GModel::current()->getFileName(), + FlGui::instance()->geoContext->input[2]->value(), + FlGui::instance()->geoContext->input[3]->value(), + FlGui::instance()->geoContext->input[4]->value(), + FlGui::instance()->geoContext->input[5]->value()); + FlGui::instance()->resetVisibility(); + drawContext::global()->draw(); + } + if(ib == 'q'){ + for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++) + for(unsigned int j = 0; j < FlGui::instance()->graph[i]->gl.size(); j++) + FlGui::instance()->graph[i]->gl[j]->addPointMode = false; + break; + } + } + + // at the end, not during creation to avoid having things jumping around + SetBoundingBox(); + Msg::StatusGl(""); +} + +static void add_new_multiline(std::string type) +{ + opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); + opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); + drawContext::global()->draw(); + + std::vector<int> p; + while(1) { + if(p.empty()) + Msg::StatusGl("Select control points\n" + "[Press 'e' to end selection or 'q' to abort]"); + else + Msg::StatusGl("Select control points\n" + "[Press 'e' to end selection, 'u' to undo last selection " + "or 'q' to abort]"); + char ib = FlGui::instance()->selectEntity(ENT_POINT); + if(ib == 'l') { + for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){ + FlGui::instance()->selectedVertices[i]->setSelection(1); + p.push_back(FlGui::instance()->selectedVertices[i]->tag()); + } + drawContext::global()->draw(); + } + if(ib == 'r') { + Msg::Warning("Entity de-selection not supported yet during multi-line creation"); + } + if(ib == 'e') { + if(p.size() >= 2) + add_multline(type, p, GModel::current()->getFileName()); + FlGui::instance()->resetVisibility(); + GModel::current()->setSelection(0); + drawContext::global()->draw(); + p.clear(); + } + if(ib == 'u') { + if(p.size()){ + GVertex *gv = GModel::current()->getVertexByTag(p.back()); + if(gv) gv->setSelection(0); + drawContext::global()->draw(); + p.pop_back(); + } + } + if(ib == 'q') { + GModel::current()->setSelection(0); + drawContext::global()->draw(); + break; + } + } + + Msg::StatusGl(""); +} + +static void add_new_line() +{ + opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); + opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); + drawContext::global()->draw(); + + std::vector<int> p; + while(1) { + if(p.empty()) + Msg::StatusGl("Select start point\n" + "[Press 'q' to abort]"); + if(p.size() == 1) + Msg::StatusGl("Select end point\n" + "[Press 'u' to undo last selection or 'q' to abort]"); + char ib = FlGui::instance()->selectEntity(ENT_POINT); + if(ib == 'l') { + FlGui::instance()->selectedVertices[0]->setSelection(1); + drawContext::global()->draw(); + p.push_back(FlGui::instance()->selectedVertices[0]->tag()); + } + if(ib == 'r') { + Msg::Warning("Entity de-selection not supported yet during line creation"); + } + if(ib == 'u') { + if(p.size()){ + GVertex *gv = GModel::current()->getVertexByTag(p.back()); + if(gv) gv->setSelection(0); + drawContext::global()->draw(); + p.pop_back(); + } + } + if(ib == 'q') { + GModel::current()->setSelection(0); + drawContext::global()->draw(); + break; + } + if(p.size() == 2) { + add_multline("Line", p, GModel::current()->getFileName()); + FlGui::instance()->resetVisibility(); + GModel::current()->setSelection(0); + drawContext::global()->draw(); + p.clear(); + } + } + + Msg::StatusGl(""); +} + +static void add_new_circle() +{ + opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); + opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); + drawContext::global()->draw(); + + std::vector<int> p; + while(1) { + if(p.empty()) + Msg::StatusGl("Select start point\n" + "[Press 'q' to abort]"); + if(p.size() == 1) + Msg::StatusGl("Select center point\n" + "[Press 'u' to undo last selection or 'q' to abort]"); + if(p.size() == 2) + Msg::StatusGl("Select end point\n" + "[Press 'u' to undo last selection or 'q' to abort]"); + char ib = FlGui::instance()->selectEntity(ENT_POINT); + if(ib == 'l') { + FlGui::instance()->selectedVertices[0]->setSelection(1); + drawContext::global()->draw(); + p.push_back(FlGui::instance()->selectedVertices[0]->tag()); + } + if(ib == 'r') { + Msg::Warning("Entity de-selection not supported yet during circle creation"); + } + if(ib == 'u') { + if(p.size()){ + GVertex *gv = GModel::current()->getVertexByTag(p.back()); + if(gv) gv->setSelection(0); + drawContext::global()->draw(); + p.pop_back(); + } + } + if(ib == 'q') { + GModel::current()->setSelection(0); + drawContext::global()->draw(); + break; + } + if(p.size() == 3) { + add_circ(p[0], p[1], p[2], GModel::current()->getFileName()); // begin, center, end + FlGui::instance()->resetVisibility(); + GModel::current()->setSelection(0); + drawContext::global()->draw(); + p.clear(); + } + } + + Msg::StatusGl(""); +} + +static void add_new_ellipse() +{ + opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); + opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); + drawContext::global()->draw(); + + std::vector<int> p; + while(1) { + if(p.empty()) + Msg::StatusGl("Select start point\n" + "[Press 'q' to abort]"); + if(p.size() == 1) + Msg::StatusGl("Select center point\n" + "[Press 'u' to undo last selection or 'q' to abort]"); + if(p.size() == 2) + Msg::StatusGl("Select major axis point\n" + "[Press 'u' to undo last selection or 'q' to abort]"); + if(p.size() == 3) + Msg::StatusGl("Select end point\n" + "[Press 'u' to undo last selection or 'q' to abort]"); + char ib = FlGui::instance()->selectEntity(ENT_POINT); + if(ib == 'l') { + FlGui::instance()->selectedVertices[0]->setSelection(1); + drawContext::global()->draw(); + p.push_back(FlGui::instance()->selectedVertices[0]->tag()); + } + if(ib == 'r') { + Msg::Warning("Entity de-selection not supported yet during ellipse creation"); + } + if(ib == 'u') { + if(p.size()){ + GVertex *gv = GModel::current()->getVertexByTag(p.back()); + if(gv) gv->setSelection(0); + drawContext::global()->draw(); + p.pop_back(); + } + } + if(ib == 'q') { + GModel::current()->setSelection(0); + drawContext::global()->draw(); + break; + } + if(p.size() == 4) { + add_ell(p[0], p[1], p[2], p[3], GModel::current()->getFileName()); + FlGui::instance()->resetVisibility(); + GModel::current()->setSelection(0); + drawContext::global()->draw(); + p.clear(); + } + } + + Msg::StatusGl(""); +} + +static int select_contour(int type, int num, List_T * List) +{ + int k = 0; + + switch (type) { + case ENT_LINE: + k = allEdgesLinked(num, List); + for(int i = 0; i < List_Nbr(List); i++) { + int ip; + List_Read(List, i, &ip); + GEdge *ge = GModel::current()->getEdgeByTag(abs(ip)); + if(ge) ge->setSelection(1); + } + break; + case ENT_SURFACE: + k = allFacesLinked(num, List); + for(int i = 0; i < List_Nbr(List); i++) { + int ip; + List_Read(List, i, &ip); + GFace *gf = GModel::current()->getFaceByTag(abs(ip)); + if(gf) gf->setSelection(1); + } + break; + } + + drawContext::global()->draw(); + return k; +} + +static void add_new_surface_volume(int mode) +{ + List_T *List1 = List_Create(10, 10, sizeof(int)); + List_T *List2 = List_Create(10, 10, sizeof(int)); + int type; + if(mode == 2) { + type = ENT_SURFACE; + opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1); + opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1); + } + else { + type = ENT_LINE; + opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); + opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1); + } + drawContext::global()->draw(); + + while(1) { + List_Reset(List1); + List_Reset(List2); + + while(1) { + if(type == ENT_LINE){ + if(!List_Nbr(List1)) + Msg::StatusGl("Select surface boundary\n" + "[Press 'q' to abort]"); + else + Msg::StatusGl("Select surface boundary\n" + "[Press 'u' to undo last selection or 'q' to abort]"); + } + else{ + if(!List_Nbr(List1)) + Msg::StatusGl("Select volume boundary\n" + "[Press 'q' to abort]"); + else + Msg::StatusGl("Select volume boundary\n" + "[Press 'u' to undo last selection or 'q' to abort]"); + } + + char ib = FlGui::instance()->selectEntity(type); + if(ib == 'q') { + GModel::current()->setSelection(0); + drawContext::global()->draw(); + goto stopall; + } + if(ib == 'u') { + if(List_Nbr(List1) > 0){ + int num; + List_Read(List1, List_Nbr(List1)-1, &num); + if(type == ENT_LINE){ + GEdge *ge = GModel::current()->getEdgeByTag(abs(num)); + if(ge) ge->setSelection(0); + } + else{ + GFace *gf = GModel::current()->getFaceByTag(abs(num)); + if(gf) gf->setSelection(0); + } + List_Pop(List1); + drawContext::global()->draw(); + } + } + if(ib == 'r') { + Msg::Warning("Entity de-selection not supported yet during " + "surface/volume creation"); + } + if(ib == 'l') { + int num = (type == ENT_LINE) ? + FlGui::instance()->selectedEdges[0]->tag() : + FlGui::instance()->selectedFaces[0]->tag(); + if(select_contour(type, num, List1)) { + if(type == ENT_LINE) + add_lineloop(List1, GModel::current()->getFileName(), &num); + else + add_surfloop(List1, GModel::current()->getFileName(), &num); + List_Reset(List1); + List_Add(List2, &num); + while(1) { + if(!List_Nbr(List1)) + Msg::StatusGl("Select hole boundaries (if none, press 'e')\n" + "[Press 'e' to end selection or 'q' to abort]"); + else + Msg::StatusGl("Select hole boundaries\n" + "[Press 'e' to end selection, 'u' to undo last selection " + "or 'q' to abort]"); + ib = FlGui::instance()->selectEntity(type); + if(ib == 'q') { + GModel::current()->setSelection(0); + drawContext::global()->draw(); + goto stopall; + } + if(ib == 'e') { + GModel::current()->setSelection(0); + drawContext::global()->draw(); + List_Reset(List1); + break; + } + if(ib == 'u') { + if(List_Nbr(List1) > 0){ + int num; + List_Read(List1, List_Nbr(List1)-1, &num); + if(type == ENT_LINE){ + GEdge *ge = GModel::current()->getEdgeByTag(abs(num)); + if(ge) ge->setSelection(0); + } + else{ + GFace *gf = GModel::current()->getFaceByTag(abs(num)); + if(gf) gf->setSelection(0); + } + List_Pop(List1); + drawContext::global()->draw(); + } + } + if(ib == 'l') { + int size = (type == ENT_LINE) ? + FlGui::instance()->selectedEdges.size() : + FlGui::instance()->selectedFaces.size(); + for(int i=0;i<size;i++){ + int num = (type == ENT_LINE) ? + FlGui::instance()->selectedEdges[i]->tag() : + FlGui::instance()->selectedFaces[i]->tag(); + if(select_contour(type, num, List1)) { + if(type == ENT_LINE) + add_lineloop(List1, GModel::current()->getFileName(), &num); + else + add_surfloop(List1, GModel::current()->getFileName(), &num); + List_Reset(List1); + List_Add(List2, &num); + } + } + } + if(ib == 'r') { + Msg::Warning("Entity de-selection not supported yet during " + "surface/volume creation"); + } + } + List_Unique(List2,fcmp_absint); + if(List_Nbr(List2)) { + switch (mode) { + case 0: add_surf("Plane Surface", List2, + GModel::current()->getFileName()); break; + case 1: add_surf("Ruled Surface", List2, + GModel::current()->getFileName()); break; + case 2: add_vol(List2, GModel::current()->getFileName()); break; + } + FlGui::instance()->resetVisibility(); + GModel::current()->setSelection(0); + drawContext::global()->draw(); + break; + } + } // if select_contour + } + } + } + + stopall: + List_Delete(List1); + List_Delete(List2); + + Msg::StatusGl(""); +} + +static void geometry_elementary_add_new_cb(Fl_Widget *w, void *data) +{ + if(!data) return; + + std::string str((const char*)data); + if(str == "Parameter") + FlGui::instance()->geoContext->show(0); + else if(str == "Point") + add_new_point(); + else if(str == "Line") + add_new_line(); + else if(str == "Spline") + add_new_multiline(str); + else if(str == "BSpline") + add_new_multiline(str); + else if(str == "Circle") + add_new_circle(); + else if(str == "Ellipse") + add_new_ellipse(); + else if(str == "Plane Surface") + add_new_surface_volume(0); + else if(str == "Ruled Surface") + add_new_surface_volume(1); + else if(str == "Volume") + add_new_surface_volume(2); + else + Msg::Error("Unknown entity to create: %s", str.c_str()); +} + +static void split_selection() +{ + opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); + drawContext::global()->draw(); + Msg::StatusGl("Select a line to split\n" + "[Press 'q' to abort]"); + GEdge* edge_to_split = 0; + while(1){ + char ib = FlGui::instance()->selectEntity(ENT_LINE); + if(ib == 'q') + break; + if(!FlGui::instance()->selectedEdges.empty()){ + edge_to_split = FlGui::instance()->selectedEdges[0]; + edge_to_split->setSelection(1); + break; + } + } + Msg::StatusGl(""); + if(FlGui::instance()->selectedEdges.empty()) return; + List_T *List1 = List_Create(5, 5, sizeof(int)); + Msg::StatusGl("Select break points\n" + "[Press 'e' to end selection or 'q' to abort]"); + opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); + drawContext::global()->draw(); + while(1){ + char ib = FlGui::instance()->selectEntity(ENT_POINT); + if(ib == 'q') + break; + if(ib == 'e'){ + split_edge(edge_to_split->tag(), List1, GModel::current()->getFileName()); + break; + } + for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){ + int tag = FlGui::instance()->selectedVertices[i]->tag(); + int index = List_ISearchSeq(List1, &tag, fcmp_int); + if(index < 0) List_Add(List1, &tag); + FlGui::instance()->selectedVertices[i]->setSelection(1); + } + } + Msg::StatusGl(""); + FlGui::instance()->resetVisibility(); + GModel::current()->setSelection(0); + drawContext::global()->draw(); +} + +static void action_point_line_surface_volume(int action, int mode, const char *what) +{ + int type; + const char *str; + + if(!strcmp(what, "Point")) { + type = ENT_POINT; + str = "points"; + opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); + } + else if(!strcmp(what, "Line")) { + type = ENT_LINE; + str = "lines"; + opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); + } + else if(!strcmp(what, "Surface")) { + type = ENT_SURFACE; + str = "surfaces"; + opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1); + } + else if(!strcmp(what, "Volume")) { + type = ENT_VOLUME; + str = "volumes"; + opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1); + } + else{ + Msg::Error("Unknown entity to select"); + return; + } + + if(action == 8){ + FlGui::instance()->meshContext->show(0); + } + + drawContext::global()->draw(); + + List_T *List1 = List_Create(5, 5, sizeof(int)); + while(1) { + if(!List_Nbr(List1)) + Msg::StatusGl("Select %s\n" + "[Press 'e' to end selection or 'q' to abort]", str); + else + Msg::StatusGl("Select %s\n" + "[Press 'e' to end selection, 'u' to undo last selection " + "or 'q' to abort]", str); + + char ib = FlGui::instance()->selectEntity(type); + if(ib == 'l') { + // we don't use List_Insert in order to keep the original + // ordering (this is slower, but this way undo works as + // expected) + int tag; + switch (type) { + case ENT_POINT: + for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){ + FlGui::instance()->selectedVertices[i]->setSelection(1); + tag = FlGui::instance()->selectedVertices[i]->tag(); + if(List_ISearchSeq(List1, &tag, fcmp_int) < 0) + List_Add(List1, &tag); + } + break; + case ENT_LINE: + for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){ + FlGui::instance()->selectedEdges[i]->setSelection(1); + tag = FlGui::instance()->selectedEdges[i]->tag(); + if(List_ISearchSeq(List1, &tag, fcmp_int) < 0) + List_Add(List1, &tag); + } + break; + case ENT_SURFACE: + for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++){ + FlGui::instance()->selectedFaces[i]->setSelection(1); + tag = FlGui::instance()->selectedFaces[i]->tag(); + if(List_ISearchSeq(List1, &tag, fcmp_int) < 0) + List_Add(List1, &tag); + } + break; + case ENT_VOLUME: + for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++){ + FlGui::instance()->selectedRegions[i]->setSelection(1); + tag = FlGui::instance()->selectedRegions[i]->tag(); + if(List_ISearchSeq(List1, &tag, fcmp_int) < 0) + List_Add(List1, &tag); + } + break; + } + drawContext::global()->draw(); + } + if(ib == 'r') { + // we don't use List_Suppress in order to keep the original + // ordering (this is slower, but this way undo works as + // expected) + int index, tag; + switch (type) { + case ENT_POINT: + for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){ + tag = FlGui::instance()->selectedVertices[i]->tag(); + index = List_ISearchSeq(List1, &tag, fcmp_int); + if(index >= 0) List_PSuppress(List1, index); + FlGui::instance()->selectedVertices[i]->setSelection(0); + } + break; + case ENT_LINE: + for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){ + tag = FlGui::instance()->selectedEdges[i]->tag(); + index = List_ISearchSeq(List1, &tag, fcmp_int); + if(index >= 0) List_PSuppress(List1, index); + FlGui::instance()->selectedEdges[i]->setSelection(0); + } + break; + case ENT_SURFACE: + for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++){ + tag = FlGui::instance()->selectedFaces[i]->tag(); + index = List_ISearchSeq(List1, &tag, fcmp_int); + if(index >= 0) List_PSuppress(List1, index); + FlGui::instance()->selectedFaces[i]->setSelection(0); + } + break; + case ENT_VOLUME: + for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++){ + tag = FlGui::instance()->selectedRegions[i]->tag(); + index = List_ISearchSeq(List1, &tag, fcmp_int); + if(index >= 0) List_PSuppress(List1, index); + FlGui::instance()->selectedRegions[i]->setSelection(0); + } + break; + } + drawContext::global()->draw(); + } + if(ib == 'u') { + if(List_Nbr(List1)) { + int num; + List_Read(List1, List_Nbr(List1) - 1, &num); + if(type == ENT_POINT){ + GVertex *gv = GModel::current()->getVertexByTag(num); + if(gv) gv->setSelection(0); + } + else if(type == ENT_LINE){ + GEdge *ge = GModel::current()->getEdgeByTag(num); + if(ge) ge->setSelection(0); + } + else if(type == ENT_SURFACE){ + GFace *gf = GModel::current()->getFaceByTag(num); + if(gf) gf->setSelection(0); + } + else if(type == ENT_VOLUME){ + GRegion *gr = GModel::current()->getRegionByTag(num); + if(gr) gr->setSelection(0); + } + drawContext::global()->draw(); + List_Pop(List1); + } + } + if(ib == 'i') { + Msg::Error("Inverting selection!"); + } + if(ib == 'e') { + if(List_Nbr(List1)){ + switch (action) { + case 0: + translate(mode, List1, GModel::current()->getFileName(), what, + FlGui::instance()->geoContext->input[6]->value(), + FlGui::instance()->geoContext->input[7]->value(), + FlGui::instance()->geoContext->input[8]->value()); + break; + case 1: + rotate(mode, List1, GModel::current()->getFileName(), what, + FlGui::instance()->geoContext->input[12]->value(), + FlGui::instance()->geoContext->input[13]->value(), + FlGui::instance()->geoContext->input[14]->value(), + FlGui::instance()->geoContext->input[9]->value(), + FlGui::instance()->geoContext->input[10]->value(), + FlGui::instance()->geoContext->input[11]->value(), + FlGui::instance()->geoContext->input[15]->value()); + break; + case 2: + dilate(mode, List1, GModel::current()->getFileName(), what, + FlGui::instance()->geoContext->input[16]->value(), + FlGui::instance()->geoContext->input[17]->value(), + FlGui::instance()->geoContext->input[18]->value(), + FlGui::instance()->geoContext->input[19]->value()); + break; + case 3: + symmetry(mode, List1, GModel::current()->getFileName(), what, + FlGui::instance()->geoContext->input[20]->value(), + FlGui::instance()->geoContext->input[21]->value(), + FlGui::instance()->geoContext->input[22]->value(), + FlGui::instance()->geoContext->input[23]->value()); + break; + case 4: + extrude(List1, GModel::current()->getFileName(), what, + FlGui::instance()->geoContext->input[6]->value(), + FlGui::instance()->geoContext->input[7]->value(), + FlGui::instance()->geoContext->input[8]->value()); + break; + case 5: + protude(List1, GModel::current()->getFileName(), what, + FlGui::instance()->geoContext->input[12]->value(), + FlGui::instance()->geoContext->input[13]->value(), + FlGui::instance()->geoContext->input[14]->value(), + FlGui::instance()->geoContext->input[9]->value(), + FlGui::instance()->geoContext->input[10]->value(), + FlGui::instance()->geoContext->input[11]->value(), + FlGui::instance()->geoContext->input[15]->value()); + break; + case 6: + delet(List1, GModel::current()->getFileName(), what); + break; + case 7: + add_physical(what, List1, GModel::current()->getFileName()); + break; + case 8: + add_charlength(List1, GModel::current()->getFileName(), + FlGui::instance()->meshContext->input[0]->value()); + break; + case 9: + add_recosurf(List1, GModel::current()->getFileName()); + break; + case 10: + add_compound(what, List1, GModel::current()->getFileName()); + break; + default: + Msg::Error("Unknown action on selected entities"); + break; + } + List_Reset(List1); + FlGui::instance()->resetVisibility(); + GModel::current()->setSelection(0); + if(action <= 6) SetBoundingBox(); + drawContext::global()->draw(); + } + } + if(ib == 'q') { + GModel::current()->setSelection(0); + drawContext::global()->draw(); + break; + } + } + List_Delete(List1); + + Msg::StatusGl(""); +} + +static void geometry_elementary_add_translate_cb(Fl_Widget *w, void *data) +{ + if(!data) return; + FlGui::instance()->geoContext->show(2); + action_point_line_surface_volume(0, 1, (const char*)data); +} + +static void geometry_elementary_add_rotate_cb(Fl_Widget *w, void *data) +{ + if(!data) return; + FlGui::instance()->geoContext->show(3); + action_point_line_surface_volume(1, 1, (const char*)data); +} + +static void geometry_elementary_add_scale_cb(Fl_Widget *w, void *data) +{ + if(!data) return; + FlGui::instance()->geoContext->show(4); + action_point_line_surface_volume(2, 1, (const char*)data); +} + +static void geometry_elementary_add_symmetry_cb(Fl_Widget *w, void *data) +{ + if(!data) return; + FlGui::instance()->geoContext->show(5); + action_point_line_surface_volume(3, 1, (const char*)data); +} + +static void geometry_elementary_translate_cb(Fl_Widget *w, void *data) +{ + if(!data) return; + FlGui::instance()->geoContext->show(2); + action_point_line_surface_volume(0, 0, (const char*)data); +} + +static void geometry_elementary_rotate_cb(Fl_Widget *w, void *data) +{ + if(!data) return; + FlGui::instance()->geoContext->show(3); + action_point_line_surface_volume(1, 0, (const char*)data); +} + +static void geometry_elementary_scale_cb(Fl_Widget *w, void *data) +{ + if(!data) return; + FlGui::instance()->geoContext->show(4); + action_point_line_surface_volume(2, 0, (const char*)data); +} + +static void geometry_elementary_symmetry_cb(Fl_Widget *w, void *data) +{ + if(!data) return; + FlGui::instance()->geoContext->show(5); + action_point_line_surface_volume(3, 0, (const char*)data); +} + +static void geometry_elementary_extrude_translate_cb(Fl_Widget *w, void *data) +{ + if(!data) return; + FlGui::instance()->geoContext->show(2); + action_point_line_surface_volume(4, 0, (const char*)data); +} + +static void geometry_elementary_extrude_rotate_cb(Fl_Widget *w, void *data) +{ + if(!data) return; + FlGui::instance()->geoContext->show(3); + action_point_line_surface_volume(5, 0, (const char*)data); +} + +static void geometry_elementary_delete_cb(Fl_Widget *w, void *data) +{ + if(!data) return; + action_point_line_surface_volume(6, 0, (const char*)data); +} + +static void geometry_elementary_split_cb(Fl_Widget *w, void *data) +{ + if(!data) return; + split_selection(); +} + +static void geometry_elementary_coherence_cb(Fl_Widget *w, void *data) +{ + coherence(GModel::current()->getFileName()); +} + +static void geometry_physical_add_cb(Fl_Widget *w, void *data) +{ + if(!data) return; + std::string str((const char*)data); + if(str == "Point") + FlGui::instance()->callForSolverPlugin(0); + else if(str == "Line") + FlGui::instance()->callForSolverPlugin(1); + + action_point_line_surface_volume(7, 0, str.c_str()); +} + +void mesh_save_cb(Fl_Widget *w, void *data) +{ + std::string name = CTX::instance()->outputFileName; + if(name.empty()){ + if(CTX::instance()->mesh.fileFormat == FORMAT_AUTO) + name = GetDefaultFileName(FORMAT_MSH); + else + name = GetDefaultFileName(CTX::instance()->mesh.fileFormat); + } + if(CTX::instance()->confirmOverwrite) { + if(!StatFile(name)) + if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", + "Cancel", "Replace", 0, name.c_str())) + return; + } + CreateOutputFile(name, CTX::instance()->mesh.fileFormat); +} + +void mesh_1d_cb(Fl_Widget *w, void *data) +{ + GModel::current()->mesh(1); + drawContext::global()->draw(); +} + +void mesh_2d_cb(Fl_Widget *w, void *data) +{ + GModel::current()->mesh(2); + drawContext::global()->draw(); +} + +void mesh_3d_cb(Fl_Widget *w, void *data) +{ + GModel::current()->mesh(3); + drawContext::global()->draw(); +} + +static void mesh_delete_parts_cb(Fl_Widget *w, void *data) +{ + const char *str = (const char*)data; + int what; + + if(!strcmp(str, "elements")){ + CTX::instance()->pickElements = 1; + what = ENT_ALL; + } + else if(!strcmp(str, "lines")){ + CTX::instance()->pickElements = 0; + what = ENT_LINE; + } + else if(!strcmp(str, "surfaces")){ + CTX::instance()->pickElements = 0; + what = ENT_SURFACE; + } + else if(!strcmp(str, "volumes")){ + CTX::instance()->pickElements = 0; + what = ENT_VOLUME; + } + else + return; + + std::vector<MElement*> ele; + std::vector<GEntity*> ent; + + while(1) { + CTX::instance()->mesh.changed = ENT_ALL; + drawContext::global()->draw(); + + if(ele.size() || ent.size()) + Msg::StatusGl("Select %s\n" + "[Press 'e' to end selection, 'u' to undo last selection or " + "'q' to abort]", str); + else + Msg::StatusGl("Select %s\n" + "[Press 'e' to end selection or 'q' to abort]", str); + + char ib = FlGui::instance()->selectEntity(what); + if(ib == 'l') { + if(CTX::instance()->pickElements){ + for(unsigned int i = 0; i < FlGui::instance()->selectedElements.size(); i++){ + if(FlGui::instance()->selectedElements[i]->getVisibility() != 2){ + FlGui::instance()->selectedElements[i]->setVisibility(2); + ele.push_back(FlGui::instance()->selectedElements[i]); + } + } + } + else{ + for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){ + if(FlGui::instance()->selectedEdges[i]->getSelection() != 1){ + FlGui::instance()->selectedEdges[i]->setSelection(1); + ent.push_back(FlGui::instance()->selectedEdges[i]); + } + } + for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++){ + if(FlGui::instance()->selectedFaces[i]->getSelection() != 1){ + FlGui::instance()->selectedFaces[i]->setSelection(1); + ent.push_back(FlGui::instance()->selectedFaces[i]); + } + } + for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++){ + if(FlGui::instance()->selectedRegions[i]->getSelection() != 1){ + FlGui::instance()->selectedRegions[i]->setSelection(1); + ent.push_back(FlGui::instance()->selectedRegions[i]); + } + } + } + } + if(ib == 'r') { + if(CTX::instance()->pickElements){ + for(unsigned int i = 0; i < FlGui::instance()->selectedElements.size(); i++) + FlGui::instance()->selectedElements[i]->setVisibility(1); + } + else{ + for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++) + FlGui::instance()->selectedEdges[i]->setSelection(0); + for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++) + FlGui::instance()->selectedFaces[i]->setSelection(0); + for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++) + FlGui::instance()->selectedRegions[i]->setSelection(0); + } + } + if(ib == 'u') { + if(CTX::instance()->pickElements){ + if(ele.size()){ + ele[ele.size() - 1]->setVisibility(1); + ele.pop_back(); + } + } + else{ + if(ent.size()){ + ent[ent.size() - 1]->setSelection(0); + ent.pop_back(); + } + } + } + if(ib == 'e') { + if(CTX::instance()->pickElements){ + for(unsigned int i = 0; i < ele.size(); i++) + if(ele[i]->getVisibility() == 2) ele[i]->setVisibility(0); + } + else{ + for(unsigned int i = 0; i < ent.size(); i++) + if(ent[i]->getSelection() == 1) ent[i]->setVisibility(0); + } + GModel::current()->removeInvisibleElements(); + ele.clear(); + ent.clear(); + } + if(ib == 'q') { + GModel::current()->setSelection(0); + break; + } + } + + CTX::instance()->mesh.changed = ENT_ALL; + CTX::instance()->pickElements = 0; + drawContext::global()->draw(); + Msg::StatusGl(""); +} + +static std::vector<std::string> getInfoStrings(MElement *ele) +{ + std::vector<std::string> info; + { + std::ostringstream sstream; + sstream << "Element " << ele->getNum() << ":"; + info.push_back(sstream.str()); + } + { + std::ostringstream sstream; + const char *name; + MElement::getInfoMSH(ele->getTypeForMSH(), &name); + sstream << " " << name + << " (MSH type " << ele->getTypeForMSH() + << ", dimension "<< ele->getDim() + << ", order "<< ele->getPolynomialOrder() + << ", partition " << ele->getPartition() + << ")"; + info.push_back(sstream.str()); + } + { + std::ostringstream sstream; + sstream << " Vertices:"; + for(int i = 0; i < ele->getNumVertices(); i++) + sstream << " " << ele->getVertex(i)->getNum(); + info.push_back(sstream.str()); + } + { + std::ostringstream sstream; + SPoint3 pt = ele->barycenter(); + sstream << " Barycenter: (" << pt[0] << ", " << pt[1] << ", " << pt[2] << ")"; + info.push_back(sstream.str()); + } + { + std::ostringstream sstream; + sstream << " Quality: " + << "rho = " << ele->rhoShapeMeasure() << " " + << "gamma = " << ele->gammaShapeMeasure() << " " + << "eta = " << ele->etaShapeMeasure(); + info.push_back(sstream.str()); + } + { + std::ostringstream sstream; + double jmin, jmax; + ele->scaledJacRange(jmin, jmax); + sstream << " Scaled Jacobian range: " << jmin << " " << jmax; + info.push_back(sstream.str()); + } + { + std::ostringstream sstream; + sstream << " Inner / outer radius: " + << ele->getInnerRadius() << " / " << ele->getOuterRadius(); + info.push_back(sstream.str()); + } + return info; +} + +static void mesh_inspect_cb(Fl_Widget *w, void *data) +{ + CTX::instance()->pickElements = 1; + CTX::instance()->mesh.changed = ENT_ALL; + drawContext::global()->draw(); + + while(1) { + Msg::StatusGl("Select element\n[Press 'q' to abort]"); + char ib = FlGui::instance()->selectEntity(ENT_ALL); + if(ib == 'l') { + if(FlGui::instance()->selectedElements.size()){ + MElement *ele = FlGui::instance()->selectedElements[0]; + GModel::current()->setSelection(0); + ele->setVisibility(2); + CTX::instance()->mesh.changed = ENT_ALL; + drawContext::global()->draw(); + std::vector<std::string> info = getInfoStrings(ele); + for(unsigned int i = 0; i < info.size(); i++) + Msg::Direct("%s", info[i].c_str()); + if(CTX::instance()->tooltips){ + std::string str; + for(unsigned int i = 0; i < info.size(); i++) + str += info[i] + "\n"; + FlGui::instance()->getCurrentOpenglWindow()->drawTooltip(str); + } + else + FlGui::instance()->showMessages(); + } + } + if(ib == 'q') { + GModel::current()->setSelection(0); + break; + } + } + + CTX::instance()->pickElements = 0; + CTX::instance()->mesh.changed = ENT_ALL; + drawContext::global()->draw(); + Msg::StatusGl(""); +} + +static void mesh_degree_cb(Fl_Widget *w, void *data) +{ + int degree = (intptr_t)data; + if(degree == 2) + SetOrderN(GModel::current(), 2, CTX::instance()->mesh.secondOrderLinear, + CTX::instance()->mesh.secondOrderIncomplete); + else if (degree == 1) + SetOrder1(GModel::current()); + else // For now, use the same options as for second order meshes + SetOrderN(GModel::current(), degree, + CTX::instance()->mesh.secondOrderLinear, + CTX::instance()->mesh.secondOrderIncomplete); + CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); + drawContext::global()->draw(); +} + +static void mesh_optimize_cb(Fl_Widget *w, void *data) +{ + if(CTX::instance()->lock) { + Msg::Info("I'm busy! Ask me that later..."); + return; + } + CTX::instance()->lock = 1; + OptimizeMesh(GModel::current()); + CTX::instance()->lock = 0; + CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); + drawContext::global()->draw(); +} + +static void mesh_refine_cb(Fl_Widget *w, void *data) +{ + RefineMesh(GModel::current(), CTX::instance()->mesh.secondOrderLinear); + CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); + drawContext::global()->draw(); +} + +static void mesh_optimize_netgen_cb(Fl_Widget *w, void *data) +{ + if(CTX::instance()->lock) { + Msg::Info("I'm busy! Ask me that later..."); + return; + } + CTX::instance()->lock = 1; + OptimizeMeshNetgen(GModel::current()); + CTX::instance()->lock = 0; + CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); + drawContext::global()->draw(); +} + +static void mesh_partition_cb(Fl_Widget *w, void *data) +{ + partition_dialog(); +} + +static void mesh_define_length_cb(Fl_Widget *w, void *data) +{ + action_point_line_surface_volume(8, 0, "Point"); +} + +static void mesh_define_recombine_cb(Fl_Widget *w, void *data) +{ + action_point_line_surface_volume(9, 0, "Surface"); +} + +static void add_transfinite_embedded(int dim, bool embed) +{ + opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); + switch (dim) { + case 1: opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); break; + case 2: opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1); break; + case 3: opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1); break; + } + drawContext::global()->draw(); + + std::vector<int> p; + char ib; + while(1) { + switch (dim) { + case 1: + if(p.empty()) + Msg::StatusGl("Select lines\n" + "[Press 'e' to end selection or 'q' to abort]"); + else + Msg::StatusGl("Select lines\n" + "[Press 'e' to end selection, 'u' to undo last selection " + "or 'q' to abort]"); + ib = FlGui::instance()->selectEntity(ENT_LINE); + break; + case 2: + Msg::StatusGl("Select surface\n[Press 'q' to abort]"); + ib = FlGui::instance()->selectEntity(ENT_SURFACE); + break; + case 3: + Msg::StatusGl("Select volume\n[Press 'q' to abort]"); + ib = FlGui::instance()->selectEntity(ENT_VOLUME); + break; + default: + ib = 'l'; + break; + } + + if(ib == 'e') { + if(dim == 1) { + if(p.size()) + add_trsfline(p, GModel::current()->getFileName(), + FlGui::instance()->meshContext->choice[0]->text(), + FlGui::instance()->meshContext->input[2]->value(), + FlGui::instance()->meshContext->input[1]->value()); + } + GModel::current()->setSelection(0); + drawContext::global()->draw(); + p.clear(); + } + if(ib == 'u') { + if(dim == 1) { + if(p.size()){ + GEdge *ge = GModel::current()->getEdgeByTag(p.back()); + if(ge) ge->setSelection(0); + drawContext::global()->draw(); + p.pop_back(); + } + } + } + if(ib == 'q') { + GModel::current()->setSelection(0); + drawContext::global()->draw(); + break; + } + if(ib == 'r') { + Msg::Warning("Entity de-selection not supported yet during " + "transfinite definition"); + } + if(ib == 'l') { + switch (dim) { + case 1: + for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){ + FlGui::instance()->selectedEdges[i]->setSelection(1); + p.push_back(FlGui::instance()->selectedEdges[i]->tag()); + } + drawContext::global()->draw(); + break; + case 2: + case 3: + if(dim == 2){ + FlGui::instance()->selectedFaces[0]->setSelection(1); + drawContext::global()->draw(); + p.push_back(FlGui::instance()->selectedFaces[0]->tag()); + } + else{ + FlGui::instance()->selectedRegions[0]->setSelection(1); + drawContext::global()->draw(); + p.push_back(FlGui::instance()->selectedRegions[0]->tag()); + } + while(1) { + if(p.size() == 1) + Msg::StatusGl("Select %s points\n" + "[Press 'e' to end selection or 'q' to abort]", + embed ? "embedded" : "(ordered) boundary"); + else + Msg::StatusGl("Select %s points\n" + "[Press 'e' to end selection, 'u' to undo last selection " + "or 'q' to abort]", + embed ? "embedded" : "(ordered) boundary"); + ib = FlGui::instance()->selectEntity(ENT_POINT); + if(ib == 'l') { + for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){ + FlGui::instance()->selectedVertices[i]->setSelection(1); + p.push_back(FlGui::instance()->selectedVertices[i]->tag()); + if(!embed) break; + } + drawContext::global()->draw(); + } + if(ib == 'u') { + if(p.size() > 1){ + GVertex *gv = GModel::current()->getVertexByTag(p.back()); + if(gv) gv->setSelection(0); + drawContext::global()->draw(); + p.pop_back(); + } + } + if(ib == 'r') { + Msg::Warning("Entity de-selection not supported yet during " + "transfinite definition"); + } + if(ib == 'e') { + switch (dim) { + case 2: + if(embed && p.size()) + add_embedded("Point", p, GModel::current()->getFileName()); + else if(!embed && + (p.size() == 0 + 1 || p.size() == 3 + 1 || p.size() == 4 + 1)) + add_trsfsurf(p, GModel::current()->getFileName(), + FlGui::instance()->meshContext->choice[1]->text()); + else + Msg::Error("Wrong number of points for mesh constraint"); + break; + case 3: + if(p.size() == 6 + 1 || p.size() == 8 + 1) + add_trsfvol(p, GModel::current()->getFileName()); + else + Msg::Error("Wrong number of points for transfinite volume"); + break; + } + GModel::current()->setSelection(0); + drawContext::global()->draw(); + p.clear(); + break; + } + if(ib == 'q') { + GModel::current()->setSelection(0); + drawContext::global()->draw(); + goto stopall; + } + } + break; + } + } + } + + stopall: + Msg::StatusGl(""); +} + +static void mesh_define_transfinite_line_cb(Fl_Widget *w, void *data) +{ + FlGui::instance()->meshContext->show(1); + add_transfinite_embedded(1, false); +} + +static void mesh_define_transfinite_surface_cb(Fl_Widget *w, void *data) +{ + FlGui::instance()->meshContext->show(2); + add_transfinite_embedded(2, false); +} + +static void mesh_define_transfinite_volume_cb(Fl_Widget *w, void *data) +{ + add_transfinite_embedded(3, false); +} + +static void mesh_define_embedded_cb(Fl_Widget *w, void *data) +{ + add_transfinite_embedded(2, true); +} + +static void mesh_define_compound_entity_cb(Fl_Widget *w, void *data) +{ + action_point_line_surface_volume(10, 0, (const char *)data); +} + +// The static menus (we cannot use the 'g', 'm' 's' and 'p' mnemonics since they +// are already defined as global shortcuts) +static Fl_Menu_Item bar_table[] = { + {"&File", 0, 0, 0, FL_SUBMENU}, + {"&New...", FL_CTRL+'n', (Fl_Callback *)file_new_cb, 0}, + {"&Open...", FL_CTRL+'o', (Fl_Callback *)file_open_cb, 0}, + {"Open Recent", 0, 0, 0, FL_SUBMENU}, + {"", 0, (Fl_Callback *)file_open_recent_cb, 0}, + {"", 0, (Fl_Callback *)file_open_recent_cb, 0}, + {"", 0, (Fl_Callback *)file_open_recent_cb, 0}, + {"", 0, (Fl_Callback *)file_open_recent_cb, 0}, + {"", 0, (Fl_Callback *)file_open_recent_cb, 0}, + {0}, + {"M&erge...", FL_CTRL+FL_SHIFT+'o', (Fl_Callback *)file_merge_cb, 0}, + {"Watch Pattern...", 0, (Fl_Callback *)file_watch_cb, 0}, + {"&Clear", 0, (Fl_Callback *)file_clear_cb, 0, FL_MENU_DIVIDER}, + {"Remote", 0, 0, 0, FL_MENU_DIVIDER | FL_SUBMENU}, + {"Start...", 0, (Fl_Callback *)file_remote_cb, (void*)"start"}, + {"Merge...", 0, (Fl_Callback *)file_remote_cb, (void*)"merge"}, + {"Clear", 0, (Fl_Callback *)file_remote_cb, (void*)"clear"}, + {"Stop", 0, (Fl_Callback *)file_remote_cb, (void*)"stop"}, + {0}, + {"&Rename...", FL_CTRL+'r', (Fl_Callback *)file_rename_cb, 0}, + {"Save &As...", FL_CTRL+'s', (Fl_Callback *)file_save_as_cb, 0}, + {"Sa&ve Mesh", FL_CTRL+FL_SHIFT+'s', (Fl_Callback *)mesh_save_cb, 0}, + {"Save Options", 0, 0, 0, FL_SUBMENU | FL_MENU_DIVIDER}, + {"For Current File", 0, (Fl_Callback *)file_options_save_cb, (void*)"file"}, + {"As Default", 0, (Fl_Callback *)file_options_save_cb, (void*)"default"}, + {0}, + {"&Quit", FL_CTRL+'q', (Fl_Callback *)file_quit_cb, 0}, + {0}, + {"&Tools", 0, 0, 0, FL_SUBMENU}, + {"&Options", FL_CTRL+FL_SHIFT+'n', (Fl_Callback *)options_cb, 0}, + {"Pl&ugins", FL_CTRL+FL_SHIFT+'u', (Fl_Callback *)plugin_cb, (void*)(-1)}, + {"&Visibility", FL_CTRL+FL_SHIFT+'v', (Fl_Callback *)visibility_cb, 0}, + {"&Clipping", FL_CTRL+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0}, + {"&Manipulator", FL_CTRL+FL_SHIFT+'m', (Fl_Callback *)manip_cb, 0}, +#if defined(HAVE_3M) + {"&3M", 0, (Fl_Callback *)window3M_cb, 0, FL_MENU_DIVIDER}, +#endif + {"S&tatistics", FL_CTRL+'i', (Fl_Callback *)statistics_cb, 0}, + {"M&essage Console", FL_CTRL+'l', (Fl_Callback *)message_cb, 0}, + {0}, + {"&Window", 0, 0, 0, FL_SUBMENU}, + {"New Window", 0, (Fl_Callback *)file_window_cb, (void*)"new", FL_MENU_DIVIDER}, + {"Split Horizontally", 0, (Fl_Callback *)file_window_cb, (void*)"split_h"}, + {"Split Vertically", 0, (Fl_Callback *)file_window_cb, (void*)"split_v"}, + {"Unsplit", 0, (Fl_Callback *)file_window_cb, (void*)"split_u", FL_MENU_DIVIDER}, + {"Minimize", FL_META+'m', (Fl_Callback *)window_cb, (void*)"minimize"}, + {"Zoom", 0, (Fl_Callback *)window_cb, (void*)"zoom", FL_MENU_DIVIDER}, + {"Bring All to Front", 0, (Fl_Callback *)window_cb, (void*)"front"}, + {0}, + {"&Help", 0, 0, 0, FL_SUBMENU}, + {"On&line Documentation", 0, (Fl_Callback *)help_online_cb, 0, FL_MENU_DIVIDER}, + {"M&ouse Actions", 0, (Fl_Callback *)help_mouse_cb, 0}, + {"&Keyboard Shortcuts", 0, (Fl_Callback *)help_short_cb, 0}, + {"C&ommand Line Options", 0, (Fl_Callback *)help_command_line_cb, 0}, + {"&Current Options", 0, (Fl_Callback *)status_options_cb, (void*)"?", FL_MENU_DIVIDER}, + {"&About Gmsh", 0, (Fl_Callback *)help_about_cb, 0}, + {0}, + {0} +}; + +#if defined(__APPLE__) + +// Alternative items for the MacOS system menu bar (removed '&' shortcuts: they +// would cause spurious menu items to appear on the menu window; removed +// File->Quit) +static Fl_Menu_Item sysbar_table[] = { + {"File", 0, 0, 0, FL_SUBMENU}, + {"New...", FL_META+'n', (Fl_Callback *)file_new_cb, 0}, + {"Open...", FL_META+'o', (Fl_Callback *)file_open_cb, 0}, + {"Open Recent", 0, 0, 0, FL_SUBMENU}, + {"", 0, (Fl_Callback *)file_open_recent_cb, 0}, + {"", 0, (Fl_Callback *)file_open_recent_cb, 0}, + {"", 0, (Fl_Callback *)file_open_recent_cb, 0}, + {"", 0, (Fl_Callback *)file_open_recent_cb, 0}, + {"", 0, (Fl_Callback *)file_open_recent_cb, 0}, + {0}, + {"Merge...", FL_META+FL_SHIFT+'o', (Fl_Callback *)file_merge_cb, 0}, + {"Watch Pattern...", 0, (Fl_Callback *)file_watch_cb, 0}, + {"Clear", 0, (Fl_Callback *)file_clear_cb, 0, FL_MENU_DIVIDER}, + {"Remote", 0, 0, 0, FL_MENU_DIVIDER | FL_SUBMENU}, + {"Start...", 0, (Fl_Callback *)file_remote_cb, (void*)"start"}, + {"Merge...", 0, (Fl_Callback *)file_remote_cb, (void*)"merge"}, + {"Clear", 0, (Fl_Callback *)file_remote_cb, (void*)"clear"}, + {"Stop", 0, (Fl_Callback *)file_remote_cb, (void*)"stop"}, + {0}, + {"Rename...", FL_META+'r', (Fl_Callback *)file_rename_cb, 0}, + {"Save As...", FL_META+'s', (Fl_Callback *)file_save_as_cb, 0}, + {"Save Mesh", FL_META+FL_SHIFT+'s', (Fl_Callback *)mesh_save_cb, 0}, + {"Save Options", 0, 0, 0, FL_SUBMENU}, + {"For Current File", 0, (Fl_Callback *)file_options_save_cb, (void*)"file"}, + {"As Default", 0, (Fl_Callback *)file_options_save_cb, (void*)"default"}, + {0}, + {0}, + {"Tools", 0, 0, 0, FL_SUBMENU}, + {"Options", FL_META+FL_SHIFT+'n', (Fl_Callback *)options_cb, 0}, + {"Plugins", FL_META+FL_SHIFT+'u', (Fl_Callback *)plugin_cb, (void*)(-1)}, + {"Visibility", FL_META+FL_SHIFT+'v', (Fl_Callback *)visibility_cb, 0}, + {"Clipping", FL_META+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0}, + {"Manipulator", FL_META+FL_SHIFT+'m', (Fl_Callback *)manip_cb, 0}, +#if defined(HAVE_3M) + {"3M", 0, (Fl_Callback *)window3M_cb, 0, FL_MENU_DIVIDER}, +#endif + {"Statistics", FL_META+'i', (Fl_Callback *)statistics_cb, 0}, + {"Message Console", FL_META+'l', (Fl_Callback *)message_cb, 0}, + {0}, + {"Window", 0, 0, 0, FL_SUBMENU}, + {"New Window", 0, (Fl_Callback *)file_window_cb, (void*)"new", FL_MENU_DIVIDER}, + {"Split Horizontally", 0, (Fl_Callback *)file_window_cb, (void*)"split_h"}, + {"Split Vertically", 0, (Fl_Callback *)file_window_cb, (void*)"split_v"}, + {"Unsplit", 0, (Fl_Callback *)file_window_cb, (void*)"split_u", FL_MENU_DIVIDER}, + {"Minimize", FL_META+'m', (Fl_Callback *)window_cb, (void*)"minimize"}, + {"Zoom", 0, (Fl_Callback *)window_cb, (void*)"zoom", FL_MENU_DIVIDER}, + {"Bring All to Front", 0, (Fl_Callback *)window_cb, (void*)"front"}, + {0}, + {"Help", 0, 0, 0, FL_SUBMENU}, + {"Online Documentation", 0, (Fl_Callback *)help_online_cb, 0, FL_MENU_DIVIDER}, + {"Mouse Actions", 0, (Fl_Callback *)help_mouse_cb, 0}, + {"Keyboard Shortcuts", 0, (Fl_Callback *)help_short_cb, 0}, + {"Command Line Options", 0, (Fl_Callback *)help_command_line_cb, 0}, + {"Current Options", 0, (Fl_Callback *)status_options_cb, (void*)"?"}, + {0}, + {0} +}; + +#endif // Icons for the satus bar #define vv(x,y) fl_vertex(x,y) @@ -285,7 +2426,7 @@ void status_options_cb(Fl_Widget *w, void *data) static int old_ve = (int)opt_mesh_volumes_edges(0, GMSH_GET, 0.); static int old_vf = (int)opt_mesh_volumes_faces(0, GMSH_GET, 0.); if(!value){ // retore visibility - Msg::StatusBar(2, false, "Mesh display restored"); + Msg::StatusBar(false, "Mesh display restored"); value = 1; opt_mesh_points(0, GMSH_SET | GMSH_GUI, old_p); opt_mesh_lines(0, GMSH_SET | GMSH_GUI, old_l); @@ -295,7 +2436,7 @@ void status_options_cb(Fl_Widget *w, void *data) opt_mesh_volumes_faces(0, GMSH_SET | GMSH_GUI, old_vf); } else{ - Msg::StatusBar(2, false, "Mesh display OFF"); + Msg::StatusBar(false, "Mesh display OFF"); value = 0; old_p = (int)opt_mesh_points(0, GMSH_GET, 0.); old_l = (int)opt_mesh_lines(0, GMSH_GET, 0.); @@ -454,6 +2595,7 @@ void message_cb(Fl_Widget *w, void *data) { graphicWindow *g = getGraphicWindow (FlGui::instance()->getCurrentOpenglWindow()->parent()); + if(!g->browser) return; if(g->browser->h()) g->hideMessages(); else @@ -528,20 +2670,33 @@ graphicWindow::graphicWindow(bool main, int numTiles) : _autoScrollMessages(true first = false; } + int mh = main ? BH : 0; // menu bar height +#if defined(__APPLE__) + if(CTX::instance()->systemMenuBar) mh = 0; +#endif int sh = 2 * FL_NORMAL_SIZE - 4; // status bar height int sw = FL_NORMAL_SIZE + 3; // status button width - int width = CTX::instance()->glSize[0]; - int mheight = 10; // dummy (nonzero) - int glheight = CTX::instance()->glSize[1] - mheight; - int height = glheight + mheight + sh; + int mheight = main ? 10 : 0; // dummy (nonzero) + int glheight = CTX::instance()->glSize[1] - mheight; + int height = mh + glheight + mheight + sh; // make sure height < screen height if(height > Fl::h()){ height = Fl::h(); - glheight = height - mheight - sh; + glheight = height - mh - mheight - sh; CTX::instance()->glSize[1] = glheight; } + int twidth = main ? (13 * sw + 2 * FL_NORMAL_SIZE + 2) : 0; + int glwidth = CTX::instance()->glSize[0] - twidth; + int width = glwidth + twidth; + // make sure width < screen width + if(width > Fl::w()){ + width = Fl::w(); + glwidth = width - twidth; + CTX::instance()->glSize[0] = glwidth; + } + // the graphic window should be a "normal" window (neither modal nor // non-modal) if(main){ @@ -553,70 +2708,92 @@ graphicWindow::graphicWindow(bool main, int numTiles) : _autoScrollMessages(true win->callback(remove_graphic_window_cb); } + sysbar = 0; + bar = 0; + if(main){ +#if defined(__APPLE__) + if(CTX::instance()->systemMenuBar){ + sysbar = new Fl_Sys_Menu_Bar(1, 1, 1, 1); + sysbar->menu(sysbar_table); + sysbar->global(); + fillRecentHistoryMenu(); + } + else{ +#endif + bar = new Fl_Menu_Bar(0, 0, width, BH); + bar->menu(bar_table); + bar->box(FL_UP_BOX); + bar->global(); + fillRecentHistoryMenu(); +#if defined(__APPLE__) + } +#endif + } + // bottom button bar - bottom = new Fl_Box(0, glheight + mheight, width, sh); + bottom = new Fl_Box(0, mh + glheight + mheight, width, sh); bottom->box(FL_FLAT_BOX); int x = 2; int sht = sh - 4; // leave a 2 pixel border at the bottom - butt[5] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_models"); + butt[5] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "@-1gmsh_models"); butt[5]->callback(status_options_cb, (void *)"model"); butt[5]->tooltip("Select active model"); x += sw; - butt[0] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "X"); + butt[0] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "X"); butt[0]->callback(status_xyz1p_cb, (void *)"x"); butt[0]->tooltip("Set +X or -X view (Alt+x or Alt+Shift+x)"); x += sw; - butt[1] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "Y"); + butt[1] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "Y"); butt[1]->callback(status_xyz1p_cb, (void *)"y"); butt[1]->tooltip("Set +Y or -Y view (Alt+y or Alt+Shift+y)"); x += sw; - butt[2] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "Z"); + butt[2] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "Z"); butt[2]->callback(status_xyz1p_cb, (void *)"z"); butt[2]->tooltip("Set +Z or -Z view (Alt+z or Alt+Shift+z)"); x += sw; - butt[4] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_rotate"); + butt[4] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "@-1gmsh_rotate"); butt[4]->callback(status_xyz1p_cb, (void *)"r"); butt[4]->tooltip("Rotate +90 or -90 (Shift) degrees, or sync rotations (Alt)"); x += sw; - butt[3] = new Fl_Button(x, glheight + mheight + 2, 2 * FL_NORMAL_SIZE, sht, "1:1"); + butt[3] = new Fl_Button(x, mh + glheight + mheight + 2, 2 * FL_NORMAL_SIZE, sht, "1:1"); butt[3]->callback(status_xyz1p_cb, (void *)"1:1"); butt[3]->tooltip("Set unit scale, sync scale between viewports (Alt), " "or reset bounding box around visible entities (Shift)"); x += 2 * FL_NORMAL_SIZE; - butt[8] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_ortho"); + butt[8] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "@-1gmsh_ortho"); butt[8]->callback(status_options_cb, (void *)"p"); butt[8]->tooltip("Toggle projection mode (Alt+o or Alt+Shift+o)"); x += sw; - butt[12] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "M"); + butt[12] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "M"); butt[12]->callback(status_options_cb, (void *)"M"); butt[12]->tooltip("Toggle mesh visibility (Alt+m)"); x += sw; - butt[13] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_clscale"); + butt[13] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "@-1gmsh_clscale"); butt[13]->callback(status_options_cb, (void *)"clscale"); butt[13]->tooltip("Change mesh element size factor"); x += sw; - butt[9] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "S"); + butt[9] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "S"); butt[9]->callback(status_options_cb, (void *)"S"); butt[9]->tooltip("Toggle mouse selection ON/OFF (Escape)"); x += sw; - butt[6] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_rewind"); + butt[6] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "@-1gmsh_rewind"); butt[6]->callback(status_rewind_cb); butt[6]->tooltip("Rewind animation"); butt[6]->deactivate(); x += sw; - butt[10] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_back"); + butt[10] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "@-1gmsh_back"); butt[10]->callback(status_stepbackward_cb); butt[10]->tooltip("Step backward"); butt[10]->deactivate(); x += sw; - butt[7] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_play"); + butt[7] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "@-1gmsh_play"); butt[7]->callback(status_play_cb); butt[7]->tooltip("Play/pause animation"); butt[7]->deactivate(); x += sw; - butt[11] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_forward"); + butt[11] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "@-1gmsh_forward"); butt[11]->callback(status_stepforward_cb); butt[11]->tooltip("Step forward"); butt[11]->deactivate(); @@ -629,19 +2806,13 @@ graphicWindow::graphicWindow(bool main, int numTiles) : _autoScrollMessages(true } x += 2; - int wleft = (width - x) / 3 - 1; - int wright = (width - x) - (width - x) / 3 - 1; - - label[0] = new Fl_Progress(x, glheight + mheight + 2, wleft, sht); - label[1] = new Fl_Progress(x + (width - x) / 3, glheight + mheight + 2, wright, sht); - for(int i = 0; i < 2; i++) { - label[i]->box(FL_THIN_DOWN_BOX); - label[i]->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); - label[i]->color(FL_BACKGROUND_COLOR, FL_DARK2); // FL_DARK_GREEN - } + label = new Fl_Progress(x, mh + glheight + mheight + 2, width - x, sht); + label->box(FL_THIN_DOWN_BOX); + label->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); + label->color(FL_BACKGROUND_COLOR, FL_DARK2); // FL_DARK_GREEN // dummy resizable box - dummyBox *resbox = new dummyBox(x, 0, width - x, glheight); + dummyBox *resbox = new dummyBox(x, mh, width - x, glheight); win->resizable(resbox); // set mininum window size @@ -649,16 +2820,17 @@ graphicWindow::graphicWindow(bool main, int numTiles) : _autoScrollMessages(true minHeight = 100; win->size_range(minWidth, minHeight); - // tiled opengl windows - tile = new Fl_Tile(0, 0, width, glheight + mheight); + // tiled windows (opengl, messages, menu) + tile = new Fl_Tile(0, mh, glwidth + twidth, glheight + mheight); - int w2 = width / 2, h2 = glheight / 2; + int w2 = glwidth / 2, h2 = glheight / 2; if(numTiles == 2){ - gl.push_back(new openglWindow(0, 0, w2, glheight)); + gl.push_back(new openglWindow(twidth, mh, w2, glheight)); gl.back()->end(); - gl.push_back(new openglWindow(w2, 0, width - w2, glheight)); + gl.push_back(new openglWindow(twidth + w2, mh, glwidth - w2, glheight)); gl.back()->end(); } + /* else if(numTiles == 3){ gl.push_back(new openglWindow(0, 0, w2, glheight)); gl.back()->end(); @@ -676,9 +2848,9 @@ graphicWindow::graphicWindow(bool main, int numTiles) : _autoScrollMessages(true gl.back()->end(); gl.push_back(new openglWindow(w2, h2, width - w2, glheight - h2)); gl.back()->end(); - } + }*/ else{ - gl.push_back(new openglWindow(0, 0, width, glheight)); + gl.push_back(new openglWindow(twidth, mh, glwidth, glheight)); gl.back()->end(); } @@ -690,23 +2862,34 @@ graphicWindow::graphicWindow(bool main, int numTiles) : _autoScrollMessages(true } for(unsigned int i = 0; i < gl.size(); i++) gl[i]->mode(mode); - browser = new Fl_Browser(0, glheight, width, mheight); - browser->box(FL_THIN_DOWN_BOX); - browser->textfont(FL_COURIER); - browser->textsize(FL_NORMAL_SIZE - 1); - browser->type(FL_MULTI_BROWSER); - browser->callback(message_browser_cb, this); -#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3) - browser->scrollbar_size(10); // thinner scrollbars -#endif + if(main){ + browser = new Fl_Browser(twidth, mh + glheight, glwidth, mheight); + browser->box(FL_THIN_DOWN_BOX); + browser->textfont(FL_COURIER); + browser->textsize(FL_NORMAL_SIZE - 1); + browser->type(FL_MULTI_BROWSER); + browser->callback(message_browser_cb, this); + browser->scrollbar_size(std::max(10, FL_NORMAL_SIZE - 2)); // thinner scrollbars #if defined(__APPLE__) - // horizontal scrollbar is buggy on Mac when tiles are resized - browser->has_scrollbar(Fl_Browser_::VERTICAL); + // horizontal scrollbar is buggy on Mac when tiles are resized + browser->has_scrollbar(Fl_Browser_::VERTICAL); #endif + } + else{ + browser = 0; + } + + if(main){ + onelab = new onelabGroup(0, mh, twidth, height - mh - sh); + } + else{ + onelab = 0; + } + tile->end(); // resize the tile to match the prescribed sizes - tile->position(0, glheight, 0, CTX::instance()->glSize[1]); + tile->position(0, mh + glheight, 0, mh + CTX::instance()->glSize[1]); _savedMessageHeight = CTX::instance()->msgSize; win->position(CTX::instance()->glPosition[0], CTX::instance()->glPosition[1]); @@ -732,8 +2915,8 @@ void graphicWindow::split(openglWindow *g, char how) if(tile->find(g) == tile->children()) return; if(how == 'u'){ - // after many tries I cannot figure out how to do this cleanly, so - // let's be brutal :-) + // after many tries I cannot figure out how to do this cleanly, so let's be + // brutal :-) int mode = g->mode(); openglWindow::setLastHandled(0); for(unsigned int i = 0; i < gl.size(); i++){ @@ -741,7 +2924,10 @@ void graphicWindow::split(openglWindow *g, char how) delete gl[i]; } gl.clear(); - openglWindow *g2 = new openglWindow(0, 0, tile->w(), tile->h() - browser->h()); + openglWindow *g2 = new openglWindow(tile->x() + (onelab ? onelab->w() : 0), + tile->y(), + tile->w() - (onelab ? onelab->w() : 0), + tile->h() - (browser ? browser->h() : 0)); g2->end(); g2->mode(mode); gl.push_back(g2); @@ -750,7 +2936,7 @@ void graphicWindow::split(openglWindow *g, char how) } else{ // make sure browser is not zero-size when adding children - if(browser->h() == 0) resizeMessages(1); + if(browser && browser->h() == 0) resizeMessages(1); int x1 = g->x(); int y1 = g->y(); int w1 = (how == 'h') ? g->w() / 2 : g->w(); @@ -816,6 +3002,7 @@ void graphicWindow::checkAnimButtons() void graphicWindow::resizeMessages(int dh) { + if(!browser) return; for(unsigned int i = 0; i < gl.size(); i++){ if(gl[i]->y() + gl[i]->h() == browser->y()) gl[i]->resize(gl[i]->x(), gl[i]->y(), gl[i]->w(), gl[i]->h() - dh); @@ -826,7 +3013,7 @@ void graphicWindow::resizeMessages(int dh) void graphicWindow::showMessages() { - if(!win->shown()) return; + if(!browser || !win->shown()) return; if(browser->h() < 5){ int height = _savedMessageHeight; if(height < 5) height = 50; @@ -840,18 +3027,21 @@ void graphicWindow::showMessages() void graphicWindow::hideMessages() { + if(!browser) return; _savedMessageHeight = browser->h(); resizeMessages(-browser->h()); } int graphicWindow::getMessageHeight() { + if(!browser) return 0; if(!browser->h()) return _savedMessageHeight; return browser->h(); } void graphicWindow::addMessage(const char *msg) { + if(!browser) return; browser->add(msg, 0); if(_autoScrollMessages && win->shown() && browser->h() >= 10) browser->bottomline(browser->size()); @@ -859,11 +3049,14 @@ void graphicWindow::addMessage(const char *msg) void graphicWindow::clearMessages() { + if(!browser) return; browser->clear(); } void graphicWindow::saveMessages(const char *filename) { + if(!browser) return; + FILE *fp = fopen(filename, "w"); if(!fp) { @@ -871,7 +3064,7 @@ void graphicWindow::saveMessages(const char *filename) return; } - Msg::StatusBar(2, true, "Writing '%s'...", filename); + Msg::StatusBar(true, "Writing '%s'...", filename); for(int i = 1; i <= browser->size(); i++) { const char *c = browser->text(i); if(c[0] == '@') @@ -879,12 +3072,14 @@ void graphicWindow::saveMessages(const char *filename) else fprintf(fp, "%s\n", c); } - Msg::StatusBar(2, true, "Done writing '%s'", filename); + Msg::StatusBar(true, "Done writing '%s'", filename); fclose(fp); } void graphicWindow::copySelectedMessagesToClipboard() { + if(!browser) return; + std::string buff; for(int i = 1; i <= browser->size(); i++) { if(browser->selected(i)) { @@ -900,3 +3095,260 @@ void graphicWindow::copySelectedMessagesToClipboard() Fl::copy(buff.c_str(), buff.size(), 0); Fl::copy(buff.c_str(), buff.size(), 1); } + +void graphicWindow::fillRecentHistoryMenu() +{ + if(!bar && !sysbar) return; + Fl_Menu_Item *table = bar_table; +#if defined(__APPLE__) + if(CTX::instance()->systemMenuBar) + table = sysbar_table; +#endif + + for(int i = 0; i < 5; i++){ + table[4 + i].text = CTX::instance()->recentFiles[i].c_str(); + table[4 + i].user_data_ = (void*)CTX::instance()->recentFiles[i].c_str(); + } + +#if defined(__APPLE__) + if(CTX::instance()->systemMenuBar) + sysbar->menu(table); +#endif +} + +typedef struct{ + std::string label; + Fl_Callback *callback; + void *arg; +} menuItem; + +static menuItem static_modules[] = { + {"0Gmsh modules/Geometry/Elementary entities/Add/Parameter", + (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Parameter"} , + {"0Gmsh modules/Geometry/Elementary entities/Add/Point", + (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Point"} , + {"0Gmsh modules/Geometry/Elementary entities/Add/Straight line", + (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Line"} , + {"0Gmsh modules/Geometry/Elementary entities/Add/Spline", + (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Spline"} , + {"0Gmsh modules/Geometry/Elementary entities/Add/B-Spline", + (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"BSpline"} , + {"0Gmsh modules/Geometry/Elementary entities/Add/Circle arc", + (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Circle"} , + {"0Gmsh modules/Geometry/Elementary entities/Add/Ellipse arc", + (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Ellipse"} , + {"0Gmsh modules/Geometry/Elementary entities/Add/Plane surface", + (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Plane Surface"} , + {"0Gmsh modules/Geometry/Elementary entities/Add/Ruled surface", + (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Ruled Surface"} , + {"0Gmsh modules/Geometry/Elementary entities/Add/Volume", + (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Volume"} , + {"0Gmsh modules/Geometry/Elementary entities/Translate/Point", + (Fl_Callback *)geometry_elementary_translate_cb, (void*)"Point"} , + {"0Gmsh modules/Geometry/Elementary entities/Translate/Line", + (Fl_Callback *)geometry_elementary_translate_cb, (void*)"Line"} , + {"0Gmsh modules/Geometry/Elementary entities/Translate/Surface", + (Fl_Callback *)geometry_elementary_translate_cb, (void*)"Surface"} , + {"0Gmsh modules/Geometry/Elementary entities/Translate/Volume", + (Fl_Callback *)geometry_elementary_translate_cb, (void*)"Volume"} , + {"0Gmsh modules/Geometry/Elementary entities/Translate/Duplicate point", + (Fl_Callback *)geometry_elementary_add_translate_cb, (void*)"Point"} , + {"0Gmsh modules/Geometry/Elementary entities/Translate/Duplicate line", + (Fl_Callback *)geometry_elementary_add_translate_cb, (void*)"Line"} , + {"0Gmsh modules/Geometry/Elementary entities/Translate/Duplicate surface", + (Fl_Callback *)geometry_elementary_add_translate_cb, (void*)"Surface"} , + {"0Gmsh modules/Geometry/Elementary entities/Translate/Duplicate volume", + (Fl_Callback *)geometry_elementary_add_translate_cb, (void*)"Volume"} , + {"0Gmsh modules/Geometry/Elementary entities/Translate/Extrude point", + (Fl_Callback *)geometry_elementary_extrude_translate_cb, (void*)"Point"} , + {"0Gmsh modules/Geometry/Elementary entities/Translate/Extrude line", + (Fl_Callback *)geometry_elementary_extrude_translate_cb, (void*)"Line"} , + {"0Gmsh modules/Geometry/Elementary entities/Translate/Extrude surface", + (Fl_Callback *)geometry_elementary_extrude_translate_cb, (void*)"Surface"} , + {"0Gmsh modules/Geometry/Elementary entities/Rotate/Point", + (Fl_Callback *)geometry_elementary_rotate_cb, (void*)"Point"} , + {"0Gmsh modules/Geometry/Elementary entities/Rotate/Line", + (Fl_Callback *)geometry_elementary_rotate_cb, (void*)"Line"} , + {"0Gmsh modules/Geometry/Elementary entities/Rotate/Surface", + (Fl_Callback *)geometry_elementary_rotate_cb, (void*)"Surface"} , + {"0Gmsh modules/Geometry/Elementary entities/Rotate/Volume", + (Fl_Callback *)geometry_elementary_rotate_cb, (void*)"Volume"} , + {"0Gmsh modules/Geometry/Elementary entities/Rotate/Duplicate point", + (Fl_Callback *)geometry_elementary_add_rotate_cb, (void*)"Point"} , + {"0Gmsh modules/Geometry/Elementary entities/Rotate/Duplicate line", + (Fl_Callback *)geometry_elementary_add_rotate_cb, (void*)"Line"} , + {"0Gmsh modules/Geometry/Elementary entities/Rotate/Duplicate surface", + (Fl_Callback *)geometry_elementary_add_rotate_cb, (void*)"Surface"} , + {"0Gmsh modules/Geometry/Elementary entities/Rotate/Duplicate volume", + (Fl_Callback *)geometry_elementary_add_rotate_cb, (void*)"Volume"} , + {"0Gmsh modules/Geometry/Elementary entities/Rotate/Extrude point", + (Fl_Callback *)geometry_elementary_extrude_rotate_cb, (void*)"Point"} , + {"0Gmsh modules/Geometry/Elementary entities/Rotate/Extrude line", + (Fl_Callback *)geometry_elementary_extrude_rotate_cb, (void*)"Line"} , + {"0Gmsh modules/Geometry/Elementary entities/Rotate/Extrude surface", + (Fl_Callback *)geometry_elementary_extrude_rotate_cb, (void*)"Surface"} , + {"0Gmsh modules/Geometry/Elementary entities/Scale/Point", + (Fl_Callback *)geometry_elementary_scale_cb, (void*)"Point"} , + {"0Gmsh modules/Geometry/Elementary entities/Scale/Line", + (Fl_Callback *)geometry_elementary_scale_cb, (void*)"Line"} , + {"0Gmsh modules/Geometry/Elementary entities/Scale/Surface", + (Fl_Callback *)geometry_elementary_scale_cb, (void*)"Surface"} , + {"0Gmsh modules/Geometry/Elementary entities/Scale/Volume", + (Fl_Callback *)geometry_elementary_scale_cb, (void*)"Volume"} , + {"0Gmsh modules/Geometry/Elementary entities/Scale/Duplicate point", + (Fl_Callback *)geometry_elementary_add_scale_cb, (void*)"Point"} , + {"0Gmsh modules/Geometry/Elementary entities/Scale/Duplicate line", + (Fl_Callback *)geometry_elementary_add_scale_cb, (void*)"Line"} , + {"0Gmsh modules/Geometry/Elementary entities/Scale/Duplicate surface", + (Fl_Callback *)geometry_elementary_add_scale_cb, (void*)"Surface"} , + {"0Gmsh modules/Geometry/Elementary entities/Scale/Duplicate volume", + (Fl_Callback *)geometry_elementary_add_scale_cb, (void*)"Volume"} , + {"0Gmsh modules/Geometry/Elementary entities/Symmetry/Point", + (Fl_Callback *)geometry_elementary_symmetry_cb, (void*)"Point"} , + {"0Gmsh modules/Geometry/Elementary entities/Symmetry/Line", + (Fl_Callback *)geometry_elementary_symmetry_cb, (void*)"Line"} , + {"0Gmsh modules/Geometry/Elementary entities/Symmetry/Surface", + (Fl_Callback *)geometry_elementary_symmetry_cb, (void*)"Surface"} , + {"0Gmsh modules/Geometry/Elementary entities/Symmetry/Volume", + (Fl_Callback *)geometry_elementary_symmetry_cb, (void*)"Volume"} , + {"0Gmsh modules/Geometry/Elementary entities/Symmetry/Duplicate point", + (Fl_Callback *)geometry_elementary_add_symmetry_cb, (void*)"Point"} , + {"0Gmsh modules/Geometry/Elementary entities/Symmetry/Duplicate line", + (Fl_Callback *)geometry_elementary_add_symmetry_cb, (void*)"Line"} , + {"0Gmsh modules/Geometry/Elementary entities/Symmetry/Duplicate surface", + (Fl_Callback *)geometry_elementary_add_symmetry_cb, (void*)"Surface"} , + {"0Gmsh modules/Geometry/Elementary entities/Symmetry/Duplicate volume", + (Fl_Callback *)geometry_elementary_add_symmetry_cb, (void*)"Volume"} , + {"0Gmsh modules/Geometry/Elementary entities/Split/Line", + (Fl_Callback *)geometry_elementary_split_cb,(void*)"Line"}, + {"0Gmsh modules/Geometry/Elementary entities/Delete/Point", + (Fl_Callback *)geometry_elementary_delete_cb, (void*)"Point"} , + {"0Gmsh modules/Geometry/Elementary entities/Delete/Line", + (Fl_Callback *)geometry_elementary_delete_cb, (void*)"Line"} , + {"0Gmsh modules/Geometry/Elementary entities/Delete/Surface", + (Fl_Callback *)geometry_elementary_delete_cb, (void*)"Surface"} , + {"0Gmsh modules/Geometry/Elementary entities/Delete/Volume", + (Fl_Callback *)geometry_elementary_delete_cb, (void*)"Volume"} , + {"0Gmsh modules/Geometry/Physical groups/Add/Point", + (Fl_Callback *)geometry_physical_add_cb, (void*)"Point" } , + {"0Gmsh modules/Geometry/Physical groups/Add/Line", + (Fl_Callback *)geometry_physical_add_cb, (void*)"Line" } , + {"0Gmsh modules/Geometry/Physical groups/Add/Surface", + (Fl_Callback *)geometry_physical_add_cb, (void*)"Surface" } , + {"0Gmsh modules/Geometry/Physical groups/Add/Volume", + (Fl_Callback *)geometry_physical_add_cb, (void*)"Volume" } , + {"0Gmsh modules/Geometry/Coherence", + (Fl_Callback *)geometry_elementary_coherence_cb} , + {"0Gmsh modules/Geometry/Reload", + (Fl_Callback *)geometry_reload_cb} , + {"0Gmsh modules/Geometry/Edit file", + (Fl_Callback *)geometry_edit_cb} , + {"0Gmsh modules/Mesh/Define/Size fields", + (Fl_Callback *)field_cb}, + {"0Gmsh modules/Mesh/Define/Element size at points", + (Fl_Callback *)mesh_define_length_cb } , + {"0Gmsh modules/Mesh/Define/Embedded points", + (Fl_Callback *)mesh_define_embedded_cb, (void*)"point" } , + {"0Gmsh modules/Mesh/Define/Recombine", + (Fl_Callback *)mesh_define_recombine_cb } , + {"0Gmsh modules/Mesh/Define/Transfinite/Line", + (Fl_Callback *)mesh_define_transfinite_line_cb} , + {"0Gmsh modules/Mesh/Define/Transfinite/Surface", + (Fl_Callback *)mesh_define_transfinite_surface_cb} , + {"0Gmsh modules/Mesh/Define/Transfinite/Volume", + (Fl_Callback *)mesh_define_transfinite_volume_cb} , + {"0Gmsh modules/Mesh/Define/Compound/Line", + (Fl_Callback *)mesh_define_compound_entity_cb, (void*)"Line"} , + {"0Gmsh modules/Mesh/Define/Compound/Surface", + (Fl_Callback *)mesh_define_compound_entity_cb, (void*)"Surface"} , + {"0Gmsh modules/Mesh/Define/Compound/Volume", + (Fl_Callback *)mesh_define_compound_entity_cb, (void*)"Volume"} , + {"0Gmsh modules/Mesh/1D", + (Fl_Callback *)mesh_1d_cb} , + {"0Gmsh modules/Mesh/2D", + (Fl_Callback *)mesh_2d_cb} , + {"0Gmsh modules/Mesh/3D", + (Fl_Callback *)mesh_3d_cb} , + {"0Gmsh modules/Mesh/Optimize 3D", + (Fl_Callback *)mesh_optimize_cb} , +#if defined(HAVE_NETGEN) + {"0Gmsh modules/Mesh/Optimize 3D (Netgen)", + (Fl_Callback *)mesh_optimize_netgen_cb} , +#endif + {"0Gmsh modules/Mesh/Set order 1", + (Fl_Callback *)mesh_degree_cb, (void*)1}, + {"0Gmsh modules/Mesh/Set order 2", + (Fl_Callback *)mesh_degree_cb, (void*)2}, + {"0Gmsh modules/Mesh/Set order 3", + (Fl_Callback *)mesh_degree_cb, (void*)3}, + {"0Gmsh modules/Mesh/Optimize high order", + (Fl_Callback *)highordertools_cb}, + {"0Gmsh modules/Mesh/Inspect", + (Fl_Callback *)mesh_inspect_cb} , + {"0Gmsh modules/Mesh/Refine by splitting", + (Fl_Callback *)mesh_refine_cb} , +#if defined(HAVE_METIS) || defined(HAVE_CHACO) + {"0Gmsh modules/Mesh/Partition", + (Fl_Callback *)mesh_partition_cb} , +#endif + {"0Gmsh modules/Mesh/Reclassify 2D", + (Fl_Callback *)mesh_classify_cb} , +#if defined(HAVE_FOURIER_MODEL) + {"0Gmsh modules/Mesh/Reparameterize 2D", + (Fl_Callback *)mesh_parameterize_cb} , +#endif + {"0Gmsh modules/Mesh/Delete/Elements", + (Fl_Callback *)mesh_delete_parts_cb, (void*)"elements"} , + {"0Gmsh modules/Mesh/Delete/Lines", + (Fl_Callback *)mesh_delete_parts_cb, (void*)"lines"} , + {"0Gmsh modules/Mesh/Delete/Surfaces", + (Fl_Callback *)mesh_delete_parts_cb, (void*)"surfaces"} , + {"0Gmsh modules/Mesh/Delete/Volumes", + (Fl_Callback *)mesh_delete_parts_cb, (void*)"volumes"} , + {"0Gmsh modules/Mesh/Save", + (Fl_Callback *)mesh_save_cb} , +}; + +void onelabGroup::_addGmshMenus() +{ + _tree->sortorder(FL_TREE_SORT_NONE); + + // add static geometry and mesh module items + for(int i = 0; i < sizeof(static_modules) / sizeof(static_modules[0]); i++) + _addMenu(static_modules[i].label, static_modules[i].callback, static_modules[i].arg); + + // add dynamic solver module items + for(int i = 0; i < 5; i++){ + std::string name = opt_solver_name(i, GMSH_GET, ""); + if(name.size()) _addMenu("0Gmsh modules/Solver/" + name, solver_cb, (void*)i); + } + + // add dynamic post-processing module items + for(unsigned int i = 0; i < PView::list.size(); i++) _addViewMenu(i); + + _tree->sortorder(FL_TREE_SORT_ASCENDING); + + static bool first = true; + if(first){ + first = false; + Fl_Tree_Item *n0 = _tree->find_item("0Gmsh modules"); + for(Fl_Tree_Item *n = n0; n; n = n->next()){ + if(!n->is_root() && n->has_children() && n->depth() > 1) + n->close(); + } + } +} + +std::set<std::string> onelabGroup::_getClosedGmshMenus() +{ + std::set<std::string> closed; + Fl_Tree_Item *n0 = _tree->find_item("0Gmsh modules"); + for(Fl_Tree_Item *n = n0; n; n = n->next()){ + if(!n->is_root() && n->has_children() && n->is_close()){ + char path[1024]; + _tree->item_pathname(path, sizeof(path), n); + closed.insert(path); + } + } + return closed; +} diff --git a/Fltk/graphicWindow.h b/Fltk/graphicWindow.h index a5abb931dcc52c6bc7e77332538456ef7b5c5307..df08af9b159e4df5c4a3732d2c6414691baad551 100644 --- a/Fltk/graphicWindow.h +++ b/Fltk/graphicWindow.h @@ -1,4 +1,3 @@ - // Gmsh - Copyright (C) 1997-2012 C. Geuzaine, J.-F. Remacle // // See the LICENSE.txt file for license information. Please report all @@ -15,7 +14,12 @@ #include <FL/Fl_Tile.H> #include <FL/Fl_Browser.H> #include <FL/Fl_Progress.H> +#if defined(__APPLE__) +#include <FL/Fl_Sys_Menu_Bar.H> +#endif +#include <FL/Fl_Menu_Bar.H> #include "openglWindow.h" +#include "onelabGroup.h" class graphicWindow{ private: @@ -24,12 +28,17 @@ class graphicWindow{ bool _autoScrollMessages; public: Fl_Window *win; +#if defined(__APPLE__) + Fl_Sys_Menu_Bar *sysbar; +#endif + Fl_Menu_Bar *bar; Fl_Tile *tile; std::vector<openglWindow*> gl; Fl_Browser *browser; + onelabGroup *onelab; Fl_Box *bottom; Fl_Button *butt[14]; - Fl_Progress *label[2]; + Fl_Progress *label; int minWidth, minHeight; public: graphicWindow(bool main=true, int numTiles=1); @@ -48,8 +57,22 @@ class graphicWindow{ void clearMessages(); void saveMessages(const char *filename); void copySelectedMessagesToClipboard(); + void fillRecentHistoryMenu(); }; +void file_quit_cb(Fl_Widget *w, void *data); +void file_watch_cb(Fl_Widget *w, void *data); +void mod_geometry_cb(Fl_Widget *w, void *data); +void mod_mesh_cb(Fl_Widget *w, void *data); +void mod_solver_cb(Fl_Widget *w, void *data); +void mod_post_cb(Fl_Widget *w, void *data); +void mod_back_cb(Fl_Widget *w, void *data); +void mod_forward_cb(Fl_Widget *w, void *data); +void geometry_reload_cb(Fl_Widget *w, void *data); +void mesh_1d_cb(Fl_Widget *w, void *data); +void mesh_2d_cb(Fl_Widget *w, void *data); +void mesh_3d_cb(Fl_Widget *w, void *data); +void help_about_cb(Fl_Widget *w, void *data); void status_xyz1p_cb(Fl_Widget *w, void *data); void status_options_cb(Fl_Widget *w, void *data); void status_play_manual(int time, int incr, bool redraw=true); diff --git a/Fltk/inputRegion.cpp b/Fltk/inputRegion.cpp index a40857cd4d90613ff3efb53d71b99fc643977023..b1208fb23e0068a60e7d313c7c862e90c92bae23 100644 --- a/Fltk/inputRegion.cpp +++ b/Fltk/inputRegion.cpp @@ -79,7 +79,7 @@ void inputRegion::_add_butt_cb(Fl_Widget *w, void *data) int dim = ENT_ALL; // TODO use onelab::region::dim - Msg::StatusBar(3, false, "Select entities\n[Press 'e' to end]"); + Msg::StatusGl("Select entities\n[Press 'e' to end]"); while(1){ char ib = FlGui::instance()->selectEntity(dim); if(ib == 'l'){ @@ -96,7 +96,7 @@ void inputRegion::_add_butt_cb(Fl_Widget *w, void *data) break; } } - Msg::StatusBar(3, false, ""); + Msg::StatusGl(""); b->do_callback(); diff --git a/Fltk/menuWindow.cpp b/Fltk/menuWindow.cpp deleted file mode 100644 index 18bb1e8c2bdf8ea05bb033e128af33c637474f9b..0000000000000000000000000000000000000000 --- a/Fltk/menuWindow.cpp +++ /dev/null @@ -1,3101 +0,0 @@ -// Gmsh - Copyright (C) 1997-2012 C. Geuzaine, J.-F. Remacle -// -// See the LICENSE.txt file for license information. Please report all -// bugs and problems to <gmsh@geuz.org>. - -#include "GmshConfig.h" -#if !defined(HAVE_NO_STDINT_H) -#include <stdint.h> -#elif defined(HAVE_NO_INTPTR_T) -typedef unsigned long intptr_t; -#endif -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <time.h> -#include <FL/Fl_Box.H> -#include <FL/fl_ask.H> -#include <FL/filename.H> -#include "GmshMessage.h" -#include "GmshSocket.h" -#include "FlGui.h" -#include "menuWindow.h" -#include "mainWindow.h" -#include "graphicWindow.h" -#include "optionWindow.h" -#include "statisticsWindow.h" -#include "contextWindow.h" -#include "visibilityWindow.h" -#include "highOrderToolsWindow.h" -#include "clippingWindow.h" -#include "manipWindow.h" -#include "fieldWindow.h" -#include "pluginWindow.h" -#include "aboutWindow.h" -#include "onelabWindow.h" -#include "fileDialogs.h" -#include "extraDialogs.h" -#include "partitionDialog.h" -#include "projectionEditor.h" -#include "classificationEditor.h" -#include "Options.h" -#include "CommandLine.h" -#include "GModel.h" -#include "PView.h" -#include "PViewData.h" -#include "PViewOptions.h" -#include "OS.h" -#include "StringUtils.h" -#include "OpenFile.h" -#include "CreateFile.h" -#include "findLinks.h" -#include "GeoStringInterface.h" -#include "Options.h" -#include "Context.h" -#include "Generator.h" -#include "HighOrder.h" -#include "Field.h" -#if defined(HAVE_ONELAB) -#include "onelab.h" -#endif -#if defined(HAVE_3M) -#include "3M.h" -#endif - -static void file_new_cb(Fl_Widget *w, void *data) -{ - test: - if(fileChooser(FILE_CHOOSER_CREATE, "New", "", - GModel::current()->getFileName().c_str())) { - std::string name = fileChooserGetName(1); - if(!StatFile(name)){ - if(fl_choice("File '%s' already exists.\n\nDo you want to erase it?", - "Cancel", "Erase", 0, name.c_str())) - UnlinkFile(name); - else - goto test; - } - FILE *fp = fopen(name.c_str(), "w"); - if(!fp){ - Msg::Error("Unable to open file '%s'", name.c_str()); - return; - } - time_t now; - time(&now); - fprintf(fp, "// Gmsh project created on %s", ctime(&now)); - fclose(fp); - OpenProject(name); - drawContext::global()->draw(); - } -} - -#if defined(HAVE_NATIVE_FILE_CHOOSER) -# define TT "\t" -# define NN "\n" -#else -# define TT " (" -# define NN ")\t" -#endif - -static const char *input_formats = - "All Files" TT "*.*" NN - "Geometry - Gmsh GEO" TT "*.geo" NN -#if defined(HAVE_ACIS) - "Geometry - ACIS" TT "*.sat" NN -#endif -#if defined(HAVE_OCC) - "Geometry - OpenCASCADE BRep" TT "*.brep" NN - "Geometry - OpenCASCADE IGES" TT "*.{igs,iges}" NN - "Geometry - OpenCASCADE STEP" TT "*.{stp,step}" NN -#endif - "Mesh - Gmsh MSH" TT "*.msh" NN - "Mesh - Diffpack 3D" TT "*.diff" NN - "Mesh - I-deas Universal" TT "*.unv" NN -#if defined(HAVE_MED) - "Mesh - MED" TT "*.{med,mmed}" NN -#endif - "Mesh - INRIA Medit" TT "*.mesh" NN - "Mesh - Nastran Bulk Data File" TT "*.{bdf,nas}" NN - "Mesh - Plot3D Structured Mesh" TT "*.p3d" NN - "Mesh - STL Surface" TT "*.stl" NN - "Mesh - VTK" TT "*.vtk" NN - "Mesh - VRML Surface" TT "*.{wrl,vrml}" NN - "Mesh - PLY2 Surface" TT "*.ply2" NN - "Post-processing - Gmsh POS" TT "*.pos" NN -#if defined(HAVE_MED) - "Post-processing - MED" TT "*.{rmed}" NN -#endif - "Image - BMP" TT "*.bmp" NN -#if defined(HAVE_LIBJPEG) - "Image - JPEG" TT "*.{jpg,jpeg}" NN -#endif - "Image - PBM" TT "*.pbm" NN - "Image - PGM" TT "*.pgm" NN -#if defined(HAVE_LIBPNG) - "Image - PNG" TT "*.png" NN -#endif - "Image - PNM" TT "*.pnm" NN - "Image - PPM" TT "*.ppm" NN; - -static void file_open_cb(Fl_Widget *w, void *data) -{ - int n = PView::list.size(); - if(fileChooser(FILE_CHOOSER_SINGLE, "Open", input_formats, - GModel::current()->getFileName().c_str())) { - OpenProject(fileChooserGetName(1)); - drawContext::global()->draw(); - } - if(n != (int)PView::list.size()) - FlGui::instance()->menu->setContext(menu_post, 0); - if(CTX::instance()->launchOnelabAtStartup != -2) - solver_cb(0, (void*)CTX::instance()->launchOnelabAtStartup); -} - -static void file_merge_cb(Fl_Widget *w, void *data) -{ - int n = PView::list.size(); - int f = fileChooser(FILE_CHOOSER_MULTI, "Merge", input_formats, - GModel::current()->getFileName().c_str()); - if(f) { - for(int i = 1; i <= f; i++) - MergeFile(fileChooserGetName(i)); - drawContext::global()->draw(); - } - if(n != (int)PView::list.size()) - FlGui::instance()->menu->setContext(menu_post, 0); - if(CTX::instance()->launchOnelabAtStartup != -2) - solver_cb(0, (void*)CTX::instance()->launchOnelabAtStartup); -} - -static void file_open_recent_cb(Fl_Widget *w, void *data) -{ - if(!data) return; - std::string str((const char*)data); - int n = PView::list.size(); - OpenProject(str); - drawContext::global()->draw(); - if(n != (int)PView::list.size()) - FlGui::instance()->menu->setContext(menu_post, 0); -} - -static void file_clear_cb(Fl_Widget *w, void *data) -{ - ClearProject(); - drawContext::global()->draw(); -} - -static void file_remote_cb(Fl_Widget *w, void *data) -{ -#if defined(HAVE_ONELAB) - onelab::localNetworkClient *c; - onelab::server::citer it = onelab::server::instance()->findClient("GmshRemote"); - if(it == onelab::server::instance()->lastClient()){ - c = new onelab::localNetworkClient("GmshRemote", ""); - c->setSocketSwitch("-socket"); - } - else - c = (onelab::localNetworkClient*)it->second; - GmshServer *server = c->getGmshServer(); - - std::string str((const char*)data); - - if(str == "start"){ - if(server){ - Msg::Error("Cannot start: remote Gmsh is already running"); - return; - } - c->setExecutable(connectionChooser()); - if(c->getExecutable().size()) c->run(); - } - else{ - if(!server){ - Msg::Error("Cannot %s: remote Gmsh not running", str.c_str()); - return; - } - if(str == "stop"){ - server->SendString(GmshSocket::GMSH_STOP, "Disconnect!"); - } - else if(str == "merge"){ - const char *file = fl_input("Merge", "/tmp/data.pos"); - if(file) server->SendString(GmshSocket::GMSH_MERGE_FILE, file); - } - else if(str == "clear"){ - server->SendString(GmshSocket::GMSH_PARSE_STRING, "Delete All;"); - for(int i = PView::list.size() - 1; i >= 0; i--) - if(PView::list[i]->getData()->isRemote()) delete PView::list[i]; - FlGui::instance()->updateViews(); - drawContext::global()->draw(); - } - else if(str == "test"){ - server->SendString(GmshSocket::GMSH_SPEED_TEST, "Speed test"); - } - } -#endif -} - -static void file_window_cb(Fl_Widget *w, void *data) -{ - std::string str((const char*)data); - if(str == "new"){ - graphicWindow *g1 = FlGui::instance()->graph.back(); - graphicWindow *g2 = new graphicWindow(false, CTX::instance()->numTiles); - FlGui::instance()->graph.push_back(g2); - FlGui::instance()->setGraphicTitle(GModel::current()->getFileName()); - g2->win->resize(g1->win->x() + 10, g1->win->y() + 10, - g1->win->w(), g1->win->h()); - g2->win->show(); - } - else if(str == "split_h"){ - FlGui::instance()->splitCurrentOpenglWindow('h'); - } - else if(str == "split_v"){ - FlGui::instance()->splitCurrentOpenglWindow('v'); - } - else if(str == "split_u"){ - FlGui::instance()->splitCurrentOpenglWindow('u'); - } - drawContext::global()->draw(); -} - -static int _save_msh(const char *name){ return mshFileDialog(name); } -static int _save_mesh_stat(const char *name){ return meshStatFileDialog(name); } -static int _save_options(const char *name){ return optionsFileDialog(name); } -static int _save_geo(const char *name){ return geoFileDialog(name); } -static int _save_brep(const char *name){ CreateOutputFile(name, FORMAT_BREP); return 1; } -static int _save_step(const char *name){ CreateOutputFile(name, FORMAT_STEP); return 1; } -static int _save_cgns(const char *name){ return cgnsFileDialog(name); } -static int _save_unv(const char *name){ return unvFileDialog(name); } -static int _save_vtk(const char *name){ return genericMeshFileDialog - (name, "VTK Options", FORMAT_VTK, true, false); } -static int _save_diff(const char *name){ return genericMeshFileDialog - (name, "Diffpack Options", FORMAT_DIFF, true, false); } -static int _save_inp(const char *name){ return genericMeshFileDialog - (name, "Abaqus INP Options", FORMAT_INP, false, false); } -static int _save_med(const char *name){ return genericMeshFileDialog - (name, "MED Options", FORMAT_MED, false, false); } -static int _save_mesh(const char *name){ return genericMeshFileDialog - (name, "MESH Options", FORMAT_MESH, false, true); } -static int _save_mail(const char *name){ return genericMeshFileDialog - (name, "MAIL Options", FORMAT_MAIL, false, false); } -static int _save_bdf(const char *name){ return bdfFileDialog(name); } -static int _save_p3d(const char *name){ return genericMeshFileDialog - (name, "P3D Options", FORMAT_P3D, false, false); } -static int _save_ir3(const char *name){ return genericMeshFileDialog - (name, "Iridium Options", FORMAT_IR3, false, true); } -static int _save_stl(const char *name){ return genericMeshFileDialog - (name, "STL Options", FORMAT_STL, true, false); } -static int _save_vrml(const char *name){ return genericMeshFileDialog - (name, "VRML Options", FORMAT_VRML, false, false); } -static int _save_ply2(const char *name){ return genericMeshFileDialog - (name, "PLY2 Options", FORMAT_PLY2, false, false); } -static int _save_eps(const char *name){ return gl2psFileDialog - (name, "EPS Options", FORMAT_EPS); } -static int _save_gif(const char *name){ return gifFileDialog(name); } -static int _save_jpeg(const char *name){ return jpegFileDialog(name); } -static int _save_mpeg(const char *name){ return mpegFileDialog(name); } -static int _save_tex(const char *name){ return latexFileDialog(name); } -static int _save_pdf(const char *name){ return gl2psFileDialog - (name, "PDF Options", FORMAT_PDF); } -static int _save_png(const char *name){ return genericBitmapFileDialog - (name, "PNG Options", FORMAT_PNG); } -static int _save_ps(const char *name){ return gl2psFileDialog - (name, "PS Options", FORMAT_PS); } -static int _save_ppm(const char *name){ return genericBitmapFileDialog - (name, "PPM Options", FORMAT_PPM); } -static int _save_svg(const char *name){ return gl2psFileDialog - (name, "SVG Options", FORMAT_SVG); } -static int _save_yuv(const char *name){ return genericBitmapFileDialog - (name, "YUV Options", FORMAT_YUV); } -static int _save_view_pos(const char *name){ return posFileDialog(name); } -static int _save_view_med(const char *name){ return genericViewFileDialog - (name, "MED Options", 6); } -static int _save_view_txt(const char *name){ return genericViewFileDialog - (name, "TXT Options", 4); } - -static int _save_auto(const char *name) -{ - switch(GuessFileFormatFromFileName(name)){ - case FORMAT_MSH : return _save_msh(name); - case FORMAT_POS : return _save_view_pos(name); - case FORMAT_TXT : return _save_view_txt(name); - case FORMAT_OPT : return _save_options(name); - case FORMAT_GEO : return _save_geo(name); - case FORMAT_BREP : return _save_brep(name); - case FORMAT_STEP : return _save_step(name); - case FORMAT_CGNS : return _save_cgns(name); - case FORMAT_UNV : return _save_unv(name); - case FORMAT_VTK : return _save_vtk(name); - case FORMAT_MED : return _save_med(name); - case FORMAT_RMED : return _save_view_med(name); - case FORMAT_MESH : return _save_mesh(name); - case FORMAT_MAIL : return _save_mail(name); - case FORMAT_BDF : return _save_bdf(name); - case FORMAT_DIFF : return _save_diff(name); - case FORMAT_INP : return _save_inp(name); - case FORMAT_P3D : return _save_p3d(name); - case FORMAT_IR3 : return _save_ir3(name); - case FORMAT_STL : return _save_stl(name); - case FORMAT_VRML : return _save_vrml(name); - case FORMAT_PLY2 : return _save_ply2(name); - case FORMAT_EPS : return _save_eps(name); - case FORMAT_GIF : return _save_gif(name); - case FORMAT_JPEG : return _save_jpeg(name); - case FORMAT_MPEG : return _save_mpeg(name); - case FORMAT_TEX : return _save_tex(name); - case FORMAT_PDF : return _save_pdf(name); - case FORMAT_PNG : return _save_png(name); - case FORMAT_PS : return _save_ps(name); - case FORMAT_PPM : return _save_ppm(name); - case FORMAT_SVG : return _save_svg(name); - case FORMAT_YUV : return _save_yuv(name); - default : - CreateOutputFile(name, FORMAT_AUTO); - return 1; - } -} - -typedef struct{ - const char *pat; - int (*func) (const char *name); -} patXfunc; - -static void file_save_as_cb(Fl_Widget *w, void *data) -{ - static patXfunc formats[] = { - {"Guess From Extension" TT "*.*", _save_auto}, - {"Geometry - Gmsh Options" TT "*.opt", _save_options}, - {"Geometry - Gmsh Unrolled GEO" TT "*.geo", _save_geo}, -#if defined(HAVE_OCC) - {"Geometry - OpenCASCADE STEP" TT "*.step", _save_step}, - {"Geometry - OpenCASCADE BRep" TT "*.brep", _save_brep}, -#endif - {"Mesh - Gmsh MSH" TT "*.msh", _save_msh}, - {"Mesh - Abaqus INP" TT "*.inp", _save_inp}, -#if defined(HAVE_LIBCGNS) - {"Mesh - CGNS (Experimental)" TT "*.cgns", _save_cgns}, -#endif - {"Mesh - Diffpack 3D" TT "*.diff", _save_diff}, - {"Mesh - I-deas Universal" TT "*.unv", _save_unv}, - {"Mesh - Iridum" TT "*.ir3", _save_ir3}, -#if defined(HAVE_MED) - {"Mesh - MED" TT "*.med", _save_med}, -#endif - {"Mesh - INRIA Medit" TT "*.mesh", _save_mesh}, - {"Mesh - CEA Triangulation" TT "*.mail", _save_mail}, - {"Mesh - Nastran Bulk Data File" TT "*.bdf", _save_bdf}, - {"Mesh - Plot3D Structured Mesh" TT "*.p3d", _save_p3d}, - {"Mesh - STL Surface" TT "*.stl", _save_stl}, - {"Mesh - VRML Surface" TT "*.wrl", _save_vrml}, - {"Mesh - VTK" TT "*.vtk", _save_vtk}, - {"Mesh - PLY2 Surface" TT "*.ply2", _save_ply2}, - {"Post-processing - Gmsh POS" TT "*.pos", _save_view_pos}, -#if defined(HAVE_MED) - {"Post-processing - MED" TT "*.rmed", _save_view_med}, -#endif - {"Post-processing - Generic TXT" TT "*.txt", _save_view_txt}, - {"Post-processing - Mesh Statistics" TT "*.pos", _save_mesh_stat}, - {"Image - Encapsulated PostScript" TT "*.eps", _save_eps}, - {"Image - GIF" TT "*.gif", _save_gif}, -#if defined(HAVE_LIBJPEG) - {"Image - JPEG" TT "*.jpg", _save_jpeg}, -#endif - {"Image - LaTeX" TT "*.tex", _save_tex}, - {"Image - PDF" TT "*.pdf", _save_pdf}, -#if defined(HAVE_LIBPNG) - {"Image - PNG" TT "*.png", _save_png}, -#endif - {"Image - PostScript" TT "*.ps", _save_ps}, - {"Image - PPM" TT "*.ppm", _save_ppm}, - {"Image - SVG" TT "*.svg", _save_svg}, - {"Image - YUV" TT "*.yuv", _save_yuv}, -#if defined(HAVE_MPEG_ENCODE) - {"Movie - MPEG" TT "*.mpg", _save_mpeg}, -#endif - }; - int nbformats = sizeof(formats) / sizeof(formats[0]); - static char *pat = 0; - if(!pat) { - pat = new char[nbformats * 256]; - strcpy(pat, formats[0].pat); - for(int i = 1; i < nbformats; i++) { - strcat(pat, NN); - strcat(pat, formats[i].pat); - } - } - - test: - if(fileChooser(FILE_CHOOSER_CREATE, "Save As", pat, - GModel::current()->getFileName().c_str())) { - std::string name = fileChooserGetName(1); - if(CTX::instance()->confirmOverwrite) { - if(!StatFile(name)) - if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", - "Cancel", "Replace", 0, name.c_str())) - goto test; - } - int i = fileChooserGetFilter(); - if(i >= 0 && i < nbformats){ - if(!formats[i].func(name.c_str())) goto test; - } - else{ // handle any additional automatic fltk filter - if(!_save_auto(name.c_str())) goto test; - } - } -} - -static void file_options_save_cb(Fl_Widget *w, void *data) -{ - std::string str((const char*)data), fileName; - if(str == "file") - fileName = GModel::current()->getFileName() + ".opt"; - else - fileName = CTX::instance()->homeDir + CTX::instance()->optionsFileName; - Msg::StatusBar(2, true, "Writing '%s'...", fileName.c_str()); - if(str == "file") - PrintOptions(0, GMSH_FULLRC, 1, 0, fileName.c_str()); - else - PrintOptions(0, GMSH_OPTIONSRC, 1, 1, fileName.c_str()); - Msg::StatusBar(2, true, "Done writing '%s'", fileName.c_str()); -} - -static void file_rename_cb(Fl_Widget *w, void *data) -{ - test: - if(fileChooser(FILE_CHOOSER_CREATE, "Rename", "", - GModel::current()->getFileName().c_str())) { - std::string name = fileChooserGetName(1); - if(CTX::instance()->confirmOverwrite) { - if(!StatFile(name)) - if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", - "Cancel", "Replace", 0, name.c_str())) - goto test; - } - rename(GModel::current()->getFileName().c_str(), name.c_str()); - GModel::current()->setFileName(name); - GModel::current()->setName(SplitFileName(name)[1]); - FlGui::instance()->setGraphicTitle(GModel::current()->getFileName()); - drawContext::global()->draw(); - } -} - -void file_quit_cb(Fl_Widget *w, void *data) -{ - Msg::Exit(0); -} - -void file_watch_cb(Fl_Widget *w, void *data) -{ - if(w) CTX::instance()->watchFilePattern = patternChooser(); - - if(CTX::instance()->watchFilePattern.empty()) return; - - std::string pattern = FixRelativePath - (GModel::current()->getFileName(), CTX::instance()->watchFilePattern); - std::string directory = SplitFileName(pattern)[0]; - if(directory.empty()) directory = "./"; - - dirent **files = 0; - int num = fl_filename_list(directory.c_str(), &files, fl_numericsort); - if(num <= 0) return; - std::vector<std::string> matches; - for (int i = 0; i < num; i++) { - std::string name = directory + files[i]->d_name; - if(fl_filename_match(name.c_str(), pattern.c_str())) - matches.push_back(name); - free((void*)files[i]); - } - if(files) free((void*)files); - - Msg::Info("%d match%s for pattern '%s'", (int)matches.size(), - (matches.size() > 1) ? "es" : "", pattern.c_str()); - - std::set<std::string> allFiles; - for(unsigned int i = 0; i < GModel::list.size(); i++) - allFiles.insert(GetFileNameWithoutPath(GModel::list[i]->getFileName())); - for(unsigned int i = 0; i < PView::list.size(); i++) - for(int j = 0; j < PView::list[i]->getData()->getNumTimeSteps(); j++) - allFiles.insert(GetFileNameWithoutPath(PView::list[i]->getData()->getFileName(j))); - - for(unsigned int i = 0; i < matches.size(); i++) - if(allFiles.find(GetFileNameWithoutPath(matches[i])) == allFiles.end()) - MergeFile(matches[i]); - drawContext::global()->draw(); -} - -#if defined(__APPLE__) -# define CC(str) "Cmd+" str " " -#else -# define CC(str) "Ctrl+" str -#endif - -static void help_short_cb(Fl_Widget *w, void *data) -{ - Msg::Direct(" "); - Msg::Direct("Keyboard shortcuts:"); - Msg::Direct(" "); - Msg::Direct(" Left arrow Go to previous time step"); - Msg::Direct(" Right arrow Go to next time step"); - Msg::Direct(" Up arrow Make previous view visible"); - Msg::Direct(" Down arrow Make next view visible"); - Msg::Direct(" "); - Msg::Direct(" < Go back to previous context"); - Msg::Direct(" > Go forward to next context"); - Msg::Direct(" 0 Reload project file"); - Msg::Direct(" 1 or F1 Mesh lines"); - Msg::Direct(" 2 or F2 Mesh surfaces"); - Msg::Direct(" 3 or F3 Mesh volumes"); - Msg::Direct(" Escape Cancel lasso zoom/selection, toggle mouse selection ON/OFF"); - Msg::Direct(" "); - Msg::Direct(" g Go to geometry module"); - Msg::Direct(" m Go to mesh module"); - Msg::Direct(" p Go to post-processing module"); - Msg::Direct(" s Go to solver module"); - Msg::Direct(" "); - Msg::Direct(" Shift+a Bring all windows to front"); - Msg::Direct(" Shift+g Show geometry options"); - Msg::Direct(" Shift+m Show mesh options"); - Msg::Direct(" Shift+o Show general options"); - Msg::Direct(" Shift+p Show post-processing options"); - Msg::Direct(" Shift+s Show solver options"); - Msg::Direct(" Shift+u Show post-processing view plugins"); - Msg::Direct(" Shift+w Show post-processing view options"); - Msg::Direct(" Shift+Escape Enable full mouse selection"); - Msg::Direct(" "); - Msg::Direct(" " CC("i") " Show statistics window"); - Msg::Direct(" " CC("l") " Show message console"); -#if defined(__APPLE__) - Msg::Direct(" " CC("m") " Minimize window"); -#endif - Msg::Direct(" " CC("n") " Create new project file"); - Msg::Direct(" " CC("o") " Open project file"); - Msg::Direct(" " CC("q") " Quit"); - Msg::Direct(" " CC("r") " Rename project file"); - Msg::Direct(" " CC("s") " Save file as"); - Msg::Direct(" "); - Msg::Direct(" Shift+" CC("c") " Show clipping plane window"); - Msg::Direct(" Shift+" CC("m") " Show manipulator window"); - Msg::Direct(" Shift+" CC("n") " Show option window"); - Msg::Direct(" Shift+" CC("o") " Merge file(s)"); - Msg::Direct(" Shift+" CC("s") " Save mesh in default format"); - Msg::Direct(" Shift+" CC("u") " Show plugin window"); - Msg::Direct(" Shift+" CC("v") " Show visibility window"); - Msg::Direct(" "); - Msg::Direct(" Alt+a Loop through axes modes"); - Msg::Direct(" Alt+b Hide/show bounding boxes"); - Msg::Direct(" Alt+c Loop through predefined color schemes"); - Msg::Direct(" Alt+e Hide/Show element outlines for visible post-pro views"); - Msg::Direct(" Alt+f Change redraw mode (fast/full)"); - Msg::Direct(" Alt+h Hide/show all post-processing views"); - Msg::Direct(" Alt+i Hide/show all post-processing view scales"); - Msg::Direct(" Alt+l Hide/show geometry lines"); - Msg::Direct(" Alt+m Toggle visibility of all mesh entities"); - Msg::Direct(" Alt+n Hide/show all post-processing view annotations"); - Msg::Direct(" Alt+o Change projection mode (orthographic/perspective)"); - Msg::Direct(" Alt+p Hide/show geometry points"); - Msg::Direct(" Alt+r Loop through range modes for visible post-pro views"); - Msg::Direct(" Alt+s Hide/show geometry surfaces"); - Msg::Direct(" Alt+t Loop through interval modes for visible post-pro views"); - Msg::Direct(" Alt+v Hide/show geometry volumes"); - Msg::Direct(" Alt+w Enable/disable all lighting"); - Msg::Direct(" Alt+x Set X view"); - Msg::Direct(" Alt+y Set Y view"); - Msg::Direct(" Alt+z Set Z view"); - Msg::Direct(" "); - Msg::Direct(" Alt+Shift+a Hide/show small axes"); - Msg::Direct(" Alt+Shift+b Hide/show mesh volume faces"); - Msg::Direct(" Alt+Shift+d Hide/show mesh surface faces"); - Msg::Direct(" Alt+Shift+l Hide/show mesh lines"); - Msg::Direct(" Alt+Shift+o Adjust projection parameters"); - Msg::Direct(" Alt+Shift+p Hide/show mesh points"); - Msg::Direct(" Alt+Shift+s Hide/show mesh surface edges"); - Msg::Direct(" Alt+Shift+v Hide/show mesh volume edges"); - Msg::Direct(" Alt+Shift+w Reverse all mesh normals"); - Msg::Direct(" Alt+Shift+x Set -X view"); - Msg::Direct(" Alt+Shift+y Set -Y view"); - Msg::Direct(" Alt+Shift+z Set -Z view"); - Msg::Direct(" "); - FlGui::instance()->showMessages(); -} - -#undef CC - -static void help_mouse_cb(Fl_Widget *w, void *data) -{ - Msg::Direct(" "); - Msg::Direct("Mouse actions:"); - Msg::Direct(" "); - Msg::Direct(" Move - Highlight the entity under the mouse pointer"); - Msg::Direct(" and display its properties in the status bar"); - Msg::Direct(" - Resize a lasso zoom or a lasso (un)selection"); - Msg::Direct(" Left button - Rotate"); - Msg::Direct(" - Select an entity"); - Msg::Direct(" - Accept a lasso zoom or a lasso selection"); - Msg::Direct(" Ctrl+Left button Start a lasso zoom or a lasso (un)selection"); - Msg::Direct(" Middle button - Zoom"); - Msg::Direct(" - Unselect an entity"); - Msg::Direct(" - Accept a lasso zoom or a lasso unselection"); - Msg::Direct(" Ctrl+Middle button Orthogonalize display"); - Msg::Direct(" Right button - Pan"); - Msg::Direct(" - Cancel a lasso zoom or a lasso (un)selection"); - Msg::Direct(" - Pop-up menu on post-processing view button"); - Msg::Direct(" Ctrl+Right button Reset to default viewpoint"); - Msg::Direct(" "); - Msg::Direct(" For a 2 button mouse, Middle button = Shift+Left button"); - Msg::Direct(" For a 1 button mouse, Middle button = Shift+Left button, " - "Right button = Alt+Left button"); - Msg::Direct(" "); - FlGui::instance()->showMessages(); -} - -static void help_command_line_cb(Fl_Widget *w, void *data) -{ - Msg::Direct(" "); - PrintUsage("gmsh"); - FlGui::instance()->showMessages(); -} - -static void help_online_cb(Fl_Widget *w, void *data) -{ - std::string prog = FixWindowsPath(CTX::instance()->webBrowser); - SystemCall(ReplaceSubString("%s", "http://geuz.org/gmsh/doc/texinfo/", prog)); -} - -void help_about_cb(Fl_Widget *w, void *data) -{ - FlGui::instance()->about->win->show(); -} - -void mod_geometry_cb(Fl_Widget *w, void *data) -{ - FlGui::instance()->menu->setContext(menu_geometry, 0); -} - -void mod_mesh_cb(Fl_Widget *w, void *data) -{ - FlGui::instance()->menu->setContext(menu_mesh, 0); -} - -void mod_solver_cb(Fl_Widget *w, void *data) -{ - FlGui::instance()->menu->setContext(menu_solver, 0); -} - -void mod_post_cb(Fl_Widget *w, void *data) -{ - FlGui::instance()->menu->setContext(menu_post, 0); -} - -void mod_back_cb(Fl_Widget *w, void *data) -{ - FlGui::instance()->menu->setContext(0, -1); -} - -void mod_forward_cb(Fl_Widget *w, void *data) -{ - FlGui::instance()->menu->setContext(0, 1); -} - -static void geometry_elementary_cb(Fl_Widget *w, void *data) -{ - FlGui::instance()->menu->setContext(menu_geometry_elementary, 0); -} - -static void geometry_physical_cb(Fl_Widget *w, void *data) -{ - FlGui::instance()->menu->setContext(menu_geometry_physical, 0); -} - -static void geometry_edit_cb(Fl_Widget *w, void *data) -{ - std::string prog = FixWindowsPath(CTX::instance()->editor); - std::string file = FixWindowsPath(GModel::current()->getFileName()); - SystemCall(ReplaceSubString("%s", file, prog)); -} - -void geometry_reload_cb(Fl_Widget *w, void *data) -{ - std::string fileName = GModel::current()->getFileName(); - OpenProject(fileName); - drawContext::global()->draw(); -} - -static void geometry_elementary_add_cb(Fl_Widget *w, void *data) -{ - FlGui::instance()->menu->setContext(menu_geometry_elementary_add, 0); -} - -static void add_new_point() -{ - opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); - drawContext::global()->draw(); - - FlGui::instance()->geoContext->show(1); - - while(1) { - for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++) - for(unsigned int j = 0; j < FlGui::instance()->graph[i]->gl.size(); j++) - FlGui::instance()->graph[i]->gl[j]->addPointMode = true; - Msg::StatusBar(3, false, "Move mouse and/or enter coordinates\n" - "[Press 'Shift' to hold position, 'e' to add point " - "or 'q' to abort]"); - char ib = FlGui::instance()->selectEntity(ENT_NONE); - if(ib == 'e'){ - add_point(GModel::current()->getFileName(), - FlGui::instance()->geoContext->input[2]->value(), - FlGui::instance()->geoContext->input[3]->value(), - FlGui::instance()->geoContext->input[4]->value(), - FlGui::instance()->geoContext->input[5]->value()); - FlGui::instance()->resetVisibility(); - drawContext::global()->draw(); - } - if(ib == 'q'){ - for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++) - for(unsigned int j = 0; j < FlGui::instance()->graph[i]->gl.size(); j++) - FlGui::instance()->graph[i]->gl[j]->addPointMode = false; - break; - } - } - - // at the end, not during creation to avoid having things jumping around - SetBoundingBox(); - Msg::StatusBar(3, false, ""); -} - -static void add_new_multiline(std::string type) -{ - opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); - opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); - drawContext::global()->draw(); - - std::vector<int> p; - while(1) { - if(p.empty()) - Msg::StatusBar(3, false, "Select control points\n" - "[Press 'e' to end selection or 'q' to abort]"); - else - Msg::StatusBar(3, false, "Select control points\n" - "[Press 'e' to end selection, 'u' to undo last selection " - "or 'q' to abort]"); - char ib = FlGui::instance()->selectEntity(ENT_POINT); - if(ib == 'l') { - for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){ - FlGui::instance()->selectedVertices[i]->setSelection(1); - p.push_back(FlGui::instance()->selectedVertices[i]->tag()); - } - drawContext::global()->draw(); - } - if(ib == 'r') { - Msg::Warning("Entity de-selection not supported yet during multi-line creation"); - } - if(ib == 'e') { - if(p.size() >= 2) - add_multline(type, p, GModel::current()->getFileName()); - FlGui::instance()->resetVisibility(); - GModel::current()->setSelection(0); - drawContext::global()->draw(); - p.clear(); - } - if(ib == 'u') { - if(p.size()){ - GVertex *gv = GModel::current()->getVertexByTag(p.back()); - if(gv) gv->setSelection(0); - drawContext::global()->draw(); - p.pop_back(); - } - } - if(ib == 'q') { - GModel::current()->setSelection(0); - drawContext::global()->draw(); - break; - } - } - - Msg::StatusBar(3, false, ""); -} - -static void add_new_line() -{ - opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); - opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); - drawContext::global()->draw(); - - std::vector<int> p; - while(1) { - if(p.empty()) - Msg::StatusBar(3, false, "Select start point\n" - "[Press 'q' to abort]"); - if(p.size() == 1) - Msg::StatusBar(3, false, "Select end point\n" - "[Press 'u' to undo last selection or 'q' to abort]"); - char ib = FlGui::instance()->selectEntity(ENT_POINT); - if(ib == 'l') { - FlGui::instance()->selectedVertices[0]->setSelection(1); - drawContext::global()->draw(); - p.push_back(FlGui::instance()->selectedVertices[0]->tag()); - } - if(ib == 'r') { - Msg::Warning("Entity de-selection not supported yet during line creation"); - } - if(ib == 'u') { - if(p.size()){ - GVertex *gv = GModel::current()->getVertexByTag(p.back()); - if(gv) gv->setSelection(0); - drawContext::global()->draw(); - p.pop_back(); - } - } - if(ib == 'q') { - GModel::current()->setSelection(0); - drawContext::global()->draw(); - break; - } - if(p.size() == 2) { - add_multline("Line", p, GModel::current()->getFileName()); - FlGui::instance()->resetVisibility(); - GModel::current()->setSelection(0); - drawContext::global()->draw(); - p.clear(); - } - } - - Msg::StatusBar(3, false, ""); -} - -static void add_new_circle() -{ - opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); - opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); - drawContext::global()->draw(); - - std::vector<int> p; - while(1) { - if(p.empty()) - Msg::StatusBar(3, false, "Select start point\n" - "[Press 'q' to abort]"); - if(p.size() == 1) - Msg::StatusBar(3, false, "Select center point\n" - "[Press 'u' to undo last selection or 'q' to abort]"); - if(p.size() == 2) - Msg::StatusBar(3, false, "Select end point\n" - "[Press 'u' to undo last selection or 'q' to abort]"); - char ib = FlGui::instance()->selectEntity(ENT_POINT); - if(ib == 'l') { - FlGui::instance()->selectedVertices[0]->setSelection(1); - drawContext::global()->draw(); - p.push_back(FlGui::instance()->selectedVertices[0]->tag()); - } - if(ib == 'r') { - Msg::Warning("Entity de-selection not supported yet during circle creation"); - } - if(ib == 'u') { - if(p.size()){ - GVertex *gv = GModel::current()->getVertexByTag(p.back()); - if(gv) gv->setSelection(0); - drawContext::global()->draw(); - p.pop_back(); - } - } - if(ib == 'q') { - GModel::current()->setSelection(0); - drawContext::global()->draw(); - break; - } - if(p.size() == 3) { - add_circ(p[0], p[1], p[2], GModel::current()->getFileName()); // begin, center, end - FlGui::instance()->resetVisibility(); - GModel::current()->setSelection(0); - drawContext::global()->draw(); - p.clear(); - } - } - - Msg::StatusBar(3, false, ""); -} - -static void add_new_ellipse() -{ - opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); - opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); - drawContext::global()->draw(); - - std::vector<int> p; - while(1) { - if(p.empty()) - Msg::StatusBar(3, false, "Select start point\n" - "[Press 'q' to abort]"); - if(p.size() == 1) - Msg::StatusBar(3, false, "Select center point\n" - "[Press 'u' to undo last selection or 'q' to abort]"); - if(p.size() == 2) - Msg::StatusBar(3, false, "Select major axis point\n" - "[Press 'u' to undo last selection or 'q' to abort]"); - if(p.size() == 3) - Msg::StatusBar(3, false, "Select end point\n" - "[Press 'u' to undo last selection or 'q' to abort]"); - char ib = FlGui::instance()->selectEntity(ENT_POINT); - if(ib == 'l') { - FlGui::instance()->selectedVertices[0]->setSelection(1); - drawContext::global()->draw(); - p.push_back(FlGui::instance()->selectedVertices[0]->tag()); - } - if(ib == 'r') { - Msg::Warning("Entity de-selection not supported yet during ellipse creation"); - } - if(ib == 'u') { - if(p.size()){ - GVertex *gv = GModel::current()->getVertexByTag(p.back()); - if(gv) gv->setSelection(0); - drawContext::global()->draw(); - p.pop_back(); - } - } - if(ib == 'q') { - GModel::current()->setSelection(0); - drawContext::global()->draw(); - break; - } - if(p.size() == 4) { - add_ell(p[0], p[1], p[2], p[3], GModel::current()->getFileName()); - FlGui::instance()->resetVisibility(); - GModel::current()->setSelection(0); - drawContext::global()->draw(); - p.clear(); - } - } - - Msg::StatusBar(3, false, ""); -} - -static int select_contour(int type, int num, List_T * List) -{ - int k = 0; - - switch (type) { - case ENT_LINE: - k = allEdgesLinked(num, List); - for(int i = 0; i < List_Nbr(List); i++) { - int ip; - List_Read(List, i, &ip); - GEdge *ge = GModel::current()->getEdgeByTag(abs(ip)); - if(ge) ge->setSelection(1); - } - break; - case ENT_SURFACE: - k = allFacesLinked(num, List); - for(int i = 0; i < List_Nbr(List); i++) { - int ip; - List_Read(List, i, &ip); - GFace *gf = GModel::current()->getFaceByTag(abs(ip)); - if(gf) gf->setSelection(1); - } - break; - } - - drawContext::global()->draw(); - return k; -} - -static void add_new_surface_volume(int mode) -{ - List_T *List1 = List_Create(10, 10, sizeof(int)); - List_T *List2 = List_Create(10, 10, sizeof(int)); - int type; - if(mode == 2) { - type = ENT_SURFACE; - opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1); - opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1); - } - else { - type = ENT_LINE; - opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); - opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1); - } - drawContext::global()->draw(); - - while(1) { - List_Reset(List1); - List_Reset(List2); - - while(1) { - if(type == ENT_LINE){ - if(!List_Nbr(List1)) - Msg::StatusBar(3, false, "Select surface boundary\n" - "[Press 'q' to abort]"); - else - Msg::StatusBar(3, false, "Select surface boundary\n" - "[Press 'u' to undo last selection or 'q' to abort]"); - } - else{ - if(!List_Nbr(List1)) - Msg::StatusBar(3, false, "Select volume boundary\n" - "[Press 'q' to abort]"); - else - Msg::StatusBar(3, false, "Select volume boundary\n" - "[Press 'u' to undo last selection or 'q' to abort]"); - } - - char ib = FlGui::instance()->selectEntity(type); - if(ib == 'q') { - GModel::current()->setSelection(0); - drawContext::global()->draw(); - goto stopall; - } - if(ib == 'u') { - if(List_Nbr(List1) > 0){ - int num; - List_Read(List1, List_Nbr(List1)-1, &num); - if(type == ENT_LINE){ - GEdge *ge = GModel::current()->getEdgeByTag(abs(num)); - if(ge) ge->setSelection(0); - } - else{ - GFace *gf = GModel::current()->getFaceByTag(abs(num)); - if(gf) gf->setSelection(0); - } - List_Pop(List1); - drawContext::global()->draw(); - } - } - if(ib == 'r') { - Msg::Warning("Entity de-selection not supported yet during " - "surface/volume creation"); - } - if(ib == 'l') { - int num = (type == ENT_LINE) ? - FlGui::instance()->selectedEdges[0]->tag() : - FlGui::instance()->selectedFaces[0]->tag(); - if(select_contour(type, num, List1)) { - if(type == ENT_LINE) - add_lineloop(List1, GModel::current()->getFileName(), &num); - else - add_surfloop(List1, GModel::current()->getFileName(), &num); - List_Reset(List1); - List_Add(List2, &num); - while(1) { - if(!List_Nbr(List1)) - Msg::StatusBar - (3, false, "Select hole boundaries (if none, press 'e')\n" - "[Press 'e' to end selection or 'q' to abort]"); - else - Msg::StatusBar - (3, false, "Select hole boundaries\n" - "[Press 'e' to end selection, 'u' to undo last selection " - "or 'q' to abort]"); - ib = FlGui::instance()->selectEntity(type); - if(ib == 'q') { - GModel::current()->setSelection(0); - drawContext::global()->draw(); - goto stopall; - } - if(ib == 'e') { - GModel::current()->setSelection(0); - drawContext::global()->draw(); - List_Reset(List1); - break; - } - if(ib == 'u') { - if(List_Nbr(List1) > 0){ - int num; - List_Read(List1, List_Nbr(List1)-1, &num); - if(type == ENT_LINE){ - GEdge *ge = GModel::current()->getEdgeByTag(abs(num)); - if(ge) ge->setSelection(0); - } - else{ - GFace *gf = GModel::current()->getFaceByTag(abs(num)); - if(gf) gf->setSelection(0); - } - List_Pop(List1); - drawContext::global()->draw(); - } - } - if(ib == 'l') { - int size = (type == ENT_LINE) ? - FlGui::instance()->selectedEdges.size() : - FlGui::instance()->selectedFaces.size(); - for(int i=0;i<size;i++){ - int num = (type == ENT_LINE) ? - FlGui::instance()->selectedEdges[i]->tag() : - FlGui::instance()->selectedFaces[i]->tag(); - if(select_contour(type, num, List1)) { - if(type == ENT_LINE) - add_lineloop(List1, GModel::current()->getFileName(), &num); - else - add_surfloop(List1, GModel::current()->getFileName(), &num); - List_Reset(List1); - List_Add(List2, &num); - } - } - } - if(ib == 'r') { - Msg::Warning("Entity de-selection not supported yet during " - "surface/volume creation"); - } - } - List_Unique(List2,fcmp_absint); - if(List_Nbr(List2)) { - switch (mode) { - case 0: add_surf("Plane Surface", List2, - GModel::current()->getFileName()); break; - case 1: add_surf("Ruled Surface", List2, - GModel::current()->getFileName()); break; - case 2: add_vol(List2, GModel::current()->getFileName()); break; - } - FlGui::instance()->resetVisibility(); - GModel::current()->setSelection(0); - drawContext::global()->draw(); - break; - } - } // if select_contour - } - } - } - - stopall: - List_Delete(List1); - List_Delete(List2); - - Msg::StatusBar(3, false, ""); -} - -static void geometry_elementary_add_new_cb(Fl_Widget *w, void *data) -{ - if(!data){ - FlGui::instance()->menu->setContext(menu_geometry_elementary_add_new, 0); - return; - } - - std::string str((const char*)data); - if(str == "Parameter") - FlGui::instance()->geoContext->show(0); - else if(str == "Point") - add_new_point(); - else if(str == "Line") - add_new_line(); - else if(str == "Spline") - add_new_multiline(str); - else if(str == "BSpline") - add_new_multiline(str); - else if(str == "Circle") - add_new_circle(); - else if(str == "Ellipse") - add_new_ellipse(); - else if(str == "Plane Surface") - add_new_surface_volume(0); - else if(str == "Ruled Surface") - add_new_surface_volume(1); - else if(str == "Volume") - add_new_surface_volume(2); - else - Msg::Error("Unknown entity to create: %s", str.c_str()); -} - -static void split_selection() -{ - opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); - drawContext::global()->draw(); - Msg::StatusBar(3, false, "Select a line to split\n" - "[Press 'q' to abort]"); - GEdge* edge_to_split = 0; - while(1){ - char ib = FlGui::instance()->selectEntity(ENT_LINE); - if(ib == 'q') - break; - if(!FlGui::instance()->selectedEdges.empty()){ - edge_to_split = FlGui::instance()->selectedEdges[0]; - edge_to_split->setSelection(1); - break; - } - } - Msg::StatusBar(3, false, ""); - if(FlGui::instance()->selectedEdges.empty()) return; - List_T *List1 = List_Create(5, 5, sizeof(int)); - Msg::StatusBar(3, false, "Select break points\n" - "[Press 'e' to end selection or 'q' to abort]"); - opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); - drawContext::global()->draw(); - while(1){ - char ib = FlGui::instance()->selectEntity(ENT_POINT); - if(ib == 'q') - break; - if(ib == 'e'){ - split_edge(edge_to_split->tag(), List1, GModel::current()->getFileName()); - break; - } - for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){ - int tag = FlGui::instance()->selectedVertices[i]->tag(); - int index = List_ISearchSeq(List1, &tag, fcmp_int); - if(index < 0) List_Add(List1, &tag); - FlGui::instance()->selectedVertices[i]->setSelection(1); - } - } - Msg::StatusBar(3, false, ""); - FlGui::instance()->resetVisibility(); - GModel::current()->setSelection(0); - drawContext::global()->draw(); -} - -static void action_point_line_surface_volume(int action, int mode, const char *what) -{ - int type; - const char *str; - - if(!strcmp(what, "Point")) { - type = ENT_POINT; - str = "points"; - opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); - } - else if(!strcmp(what, "Line")) { - type = ENT_LINE; - str = "lines"; - opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); - } - else if(!strcmp(what, "Surface")) { - type = ENT_SURFACE; - str = "surfaces"; - opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1); - } - else if(!strcmp(what, "Volume")) { - type = ENT_VOLUME; - str = "volumes"; - opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1); - } - else{ - Msg::Error("Unknown entity to select"); - return; - } - - if(action == 8){ - FlGui::instance()->meshContext->show(0); - } - - drawContext::global()->draw(); - - List_T *List1 = List_Create(5, 5, sizeof(int)); - while(1) { - if(!List_Nbr(List1)) - Msg::StatusBar(3, false, "Select %s\n" - "[Press 'e' to end selection or 'q' to abort]", str); - else - Msg::StatusBar(3, false, "Select %s\n" - "[Press 'e' to end selection, 'u' to undo last selection " - "or 'q' to abort]", str); - - char ib = FlGui::instance()->selectEntity(type); - if(ib == 'l') { - // we don't use List_Insert in order to keep the original - // ordering (this is slower, but this way undo works as - // expected) - int tag; - switch (type) { - case ENT_POINT: - for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){ - FlGui::instance()->selectedVertices[i]->setSelection(1); - tag = FlGui::instance()->selectedVertices[i]->tag(); - if(List_ISearchSeq(List1, &tag, fcmp_int) < 0) - List_Add(List1, &tag); - } - break; - case ENT_LINE: - for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){ - FlGui::instance()->selectedEdges[i]->setSelection(1); - tag = FlGui::instance()->selectedEdges[i]->tag(); - if(List_ISearchSeq(List1, &tag, fcmp_int) < 0) - List_Add(List1, &tag); - } - break; - case ENT_SURFACE: - for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++){ - FlGui::instance()->selectedFaces[i]->setSelection(1); - tag = FlGui::instance()->selectedFaces[i]->tag(); - if(List_ISearchSeq(List1, &tag, fcmp_int) < 0) - List_Add(List1, &tag); - } - break; - case ENT_VOLUME: - for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++){ - FlGui::instance()->selectedRegions[i]->setSelection(1); - tag = FlGui::instance()->selectedRegions[i]->tag(); - if(List_ISearchSeq(List1, &tag, fcmp_int) < 0) - List_Add(List1, &tag); - } - break; - } - drawContext::global()->draw(); - } - if(ib == 'r') { - // we don't use List_Suppress in order to keep the original - // ordering (this is slower, but this way undo works as - // expected) - int index, tag; - switch (type) { - case ENT_POINT: - for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){ - tag = FlGui::instance()->selectedVertices[i]->tag(); - index = List_ISearchSeq(List1, &tag, fcmp_int); - if(index >= 0) List_PSuppress(List1, index); - FlGui::instance()->selectedVertices[i]->setSelection(0); - } - break; - case ENT_LINE: - for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){ - tag = FlGui::instance()->selectedEdges[i]->tag(); - index = List_ISearchSeq(List1, &tag, fcmp_int); - if(index >= 0) List_PSuppress(List1, index); - FlGui::instance()->selectedEdges[i]->setSelection(0); - } - break; - case ENT_SURFACE: - for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++){ - tag = FlGui::instance()->selectedFaces[i]->tag(); - index = List_ISearchSeq(List1, &tag, fcmp_int); - if(index >= 0) List_PSuppress(List1, index); - FlGui::instance()->selectedFaces[i]->setSelection(0); - } - break; - case ENT_VOLUME: - for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++){ - tag = FlGui::instance()->selectedRegions[i]->tag(); - index = List_ISearchSeq(List1, &tag, fcmp_int); - if(index >= 0) List_PSuppress(List1, index); - FlGui::instance()->selectedRegions[i]->setSelection(0); - } - break; - } - drawContext::global()->draw(); - } - if(ib == 'u') { - if(List_Nbr(List1)) { - int num; - List_Read(List1, List_Nbr(List1) - 1, &num); - if(type == ENT_POINT){ - GVertex *gv = GModel::current()->getVertexByTag(num); - if(gv) gv->setSelection(0); - } - else if(type == ENT_LINE){ - GEdge *ge = GModel::current()->getEdgeByTag(num); - if(ge) ge->setSelection(0); - } - else if(type == ENT_SURFACE){ - GFace *gf = GModel::current()->getFaceByTag(num); - if(gf) gf->setSelection(0); - } - else if(type == ENT_VOLUME){ - GRegion *gr = GModel::current()->getRegionByTag(num); - if(gr) gr->setSelection(0); - } - drawContext::global()->draw(); - List_Pop(List1); - } - } - if(ib == 'i') { - Msg::Error("Inverting selection!"); - } - if(ib == 'e') { - if(List_Nbr(List1)){ - switch (action) { - case 0: - translate(mode, List1, GModel::current()->getFileName(), what, - FlGui::instance()->geoContext->input[6]->value(), - FlGui::instance()->geoContext->input[7]->value(), - FlGui::instance()->geoContext->input[8]->value()); - break; - case 1: - rotate(mode, List1, GModel::current()->getFileName(), what, - FlGui::instance()->geoContext->input[12]->value(), - FlGui::instance()->geoContext->input[13]->value(), - FlGui::instance()->geoContext->input[14]->value(), - FlGui::instance()->geoContext->input[9]->value(), - FlGui::instance()->geoContext->input[10]->value(), - FlGui::instance()->geoContext->input[11]->value(), - FlGui::instance()->geoContext->input[15]->value()); - break; - case 2: - dilate(mode, List1, GModel::current()->getFileName(), what, - FlGui::instance()->geoContext->input[16]->value(), - FlGui::instance()->geoContext->input[17]->value(), - FlGui::instance()->geoContext->input[18]->value(), - FlGui::instance()->geoContext->input[19]->value()); - break; - case 3: - symmetry(mode, List1, GModel::current()->getFileName(), what, - FlGui::instance()->geoContext->input[20]->value(), - FlGui::instance()->geoContext->input[21]->value(), - FlGui::instance()->geoContext->input[22]->value(), - FlGui::instance()->geoContext->input[23]->value()); - break; - case 4: - extrude(List1, GModel::current()->getFileName(), what, - FlGui::instance()->geoContext->input[6]->value(), - FlGui::instance()->geoContext->input[7]->value(), - FlGui::instance()->geoContext->input[8]->value()); - break; - case 5: - protude(List1, GModel::current()->getFileName(), what, - FlGui::instance()->geoContext->input[12]->value(), - FlGui::instance()->geoContext->input[13]->value(), - FlGui::instance()->geoContext->input[14]->value(), - FlGui::instance()->geoContext->input[9]->value(), - FlGui::instance()->geoContext->input[10]->value(), - FlGui::instance()->geoContext->input[11]->value(), - FlGui::instance()->geoContext->input[15]->value()); - break; - case 6: - delet(List1, GModel::current()->getFileName(), what); - break; - case 7: - add_physical(what, List1, GModel::current()->getFileName()); - break; - case 8: - add_charlength(List1, GModel::current()->getFileName(), - FlGui::instance()->meshContext->input[0]->value()); - break; - case 9: - add_recosurf(List1, GModel::current()->getFileName()); - break; - case 10: - add_compound(what, List1, GModel::current()->getFileName()); - break; - default: - Msg::Error("Unknown action on selected entities"); - break; - } - List_Reset(List1); - FlGui::instance()->resetVisibility(); - GModel::current()->setSelection(0); - if(action <= 6) SetBoundingBox(); - drawContext::global()->draw(); - } - } - if(ib == 'q') { - GModel::current()->setSelection(0); - drawContext::global()->draw(); - break; - } - } - List_Delete(List1); - - Msg::StatusBar(3, false, ""); -} - -static void geometry_elementary_add_translate_cb(Fl_Widget *w, void *data) -{ - if(!data){ - FlGui::instance()->menu->setContext(menu_geometry_elementary_add_translate, 0); - return; - } - FlGui::instance()->geoContext->show(2); - action_point_line_surface_volume(0, 1, (const char*)data); -} - -static void geometry_elementary_add_rotate_cb(Fl_Widget *w, void *data) -{ - if(!data){ - FlGui::instance()->menu->setContext(menu_geometry_elementary_add_rotate, 0); - return; - } - FlGui::instance()->geoContext->show(3); - action_point_line_surface_volume(1, 1, (const char*)data); -} - -static void geometry_elementary_add_scale_cb(Fl_Widget *w, void *data) -{ - if(!data){ - FlGui::instance()->menu->setContext(menu_geometry_elementary_add_scale, 0); - return; - } - FlGui::instance()->geoContext->show(4); - action_point_line_surface_volume(2, 1, (const char*)data); -} - -static void geometry_elementary_add_symmetry_cb(Fl_Widget *w, void *data) -{ - if(!data){ - FlGui::instance()->menu->setContext(menu_geometry_elementary_add_symmetry, 0); - return; - } - FlGui::instance()->geoContext->show(5); - action_point_line_surface_volume(3, 1, (const char*)data); -} - -static void geometry_elementary_translate_cb(Fl_Widget *w, void *data) -{ - if(!data){ - FlGui::instance()->menu->setContext(menu_geometry_elementary_translate, 0); - return; - } - FlGui::instance()->geoContext->show(2); - action_point_line_surface_volume(0, 0, (const char*)data); -} - -static void geometry_elementary_rotate_cb(Fl_Widget *w, void *data) -{ - if(!data){ - FlGui::instance()->menu->setContext(menu_geometry_elementary_rotate, 0); - return; - } - FlGui::instance()->geoContext->show(3); - action_point_line_surface_volume(1, 0, (const char*)data); -} - -static void geometry_elementary_scale_cb(Fl_Widget *w, void *data) -{ - if(!data){ - FlGui::instance()->menu->setContext(menu_geometry_elementary_scale, 0); - return; - } - FlGui::instance()->geoContext->show(4); - action_point_line_surface_volume(2, 0, (const char*)data); -} - -static void geometry_elementary_symmetry_cb(Fl_Widget *w, void *data) -{ - if(!data){ - FlGui::instance()->menu->setContext(menu_geometry_elementary_symmetry, 0); - return; - } - FlGui::instance()->geoContext->show(5); - action_point_line_surface_volume(3, 0, (const char*)data); -} - -static void geometry_elementary_extrude_cb(Fl_Widget *w, void *data) -{ - FlGui::instance()->menu->setContext(menu_geometry_elementary_extrude, 0); -} - -static void geometry_elementary_extrude_translate_cb(Fl_Widget *w, void *data) -{ - if(!data){ - FlGui::instance()->menu->setContext(menu_geometry_elementary_extrude_translate, 0); - return; - } - FlGui::instance()->geoContext->show(2); - action_point_line_surface_volume(4, 0, (const char*)data); -} - -static void geometry_elementary_extrude_rotate_cb(Fl_Widget *w, void *data) -{ - if(!data){ - FlGui::instance()->menu->setContext(menu_geometry_elementary_extrude_rotate, 0); - return; - } - FlGui::instance()->geoContext->show(3); - action_point_line_surface_volume(5, 0, (const char*)data); -} - -static void geometry_elementary_delete_cb(Fl_Widget *w, void *data) -{ - if(!data){ - FlGui::instance()->menu->setContext(menu_geometry_elementary_delete, 0); - return; - } - action_point_line_surface_volume(6, 0, (const char*)data); -} - -static void geometry_elementary_split_cb(Fl_Widget *w, void *data) -{ - if(!data){ - FlGui::instance()->menu->setContext(menu_geometry_elementary_split, 0); - return; - } - split_selection(); -} - -static void geometry_elementary_coherence_cb(Fl_Widget *w, void *data) -{ - coherence(GModel::current()->getFileName()); -} - -static void geometry_physical_add_cb(Fl_Widget *w, void *data) -{ - if(!data){ - FlGui::instance()->menu->setContext(menu_geometry_physical_add, 0); - return; - } - std::string str((const char*)data); - if(str == "Point") - FlGui::instance()->callForSolverPlugin(0); - else if(str == "Line") - FlGui::instance()->callForSolverPlugin(1); - - action_point_line_surface_volume(7, 0, str.c_str()); -} - -void mesh_save_cb(Fl_Widget *w, void *data) -{ - std::string name = CTX::instance()->outputFileName; - if(name.empty()){ - if(CTX::instance()->mesh.fileFormat == FORMAT_AUTO) - name = GetDefaultFileName(FORMAT_MSH); - else - name = GetDefaultFileName(CTX::instance()->mesh.fileFormat); - } - if(CTX::instance()->confirmOverwrite) { - if(!StatFile(name)) - if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", - "Cancel", "Replace", 0, name.c_str())) - return; - } - CreateOutputFile(name, CTX::instance()->mesh.fileFormat); -} - -static void mesh_define_cb(Fl_Widget *w, void *data) -{ - FlGui::instance()->menu->setContext(menu_mesh_define, 0); -} - -void mesh_1d_cb(Fl_Widget *w, void *data) -{ - GModel::current()->mesh(1); - drawContext::global()->draw(); -} - -void mesh_2d_cb(Fl_Widget *w, void *data) -{ - GModel::current()->mesh(2); - drawContext::global()->draw(); -} - -void mesh_3d_cb(Fl_Widget *w, void *data) -{ - GModel::current()->mesh(3); - drawContext::global()->draw(); -} - -static void mesh_delete_cb(Fl_Widget *w, void *data) -{ - FlGui::instance()->menu->setContext(menu_mesh_delete, 0); -} - -static void mesh_delete_parts_cb(Fl_Widget *w, void *data) -{ - const char *str = (const char*)data; - int what; - - if(!strcmp(str, "elements")){ - CTX::instance()->pickElements = 1; - what = ENT_ALL; - } - else if(!strcmp(str, "lines")){ - CTX::instance()->pickElements = 0; - what = ENT_LINE; - } - else if(!strcmp(str, "surfaces")){ - CTX::instance()->pickElements = 0; - what = ENT_SURFACE; - } - else if(!strcmp(str, "volumes")){ - CTX::instance()->pickElements = 0; - what = ENT_VOLUME; - } - else - return; - - std::vector<MElement*> ele; - std::vector<GEntity*> ent; - - while(1) { - CTX::instance()->mesh.changed = ENT_ALL; - drawContext::global()->draw(); - - if(ele.size() || ent.size()) - Msg::StatusBar(3, false, "Select %s\n" - "[Press 'e' to end selection, 'u' to undo last selection or " - "'q' to abort]", str); - else - Msg::StatusBar(3, false, "Select %s\n" - "[Press 'e' to end selection or 'q' to abort]", str); - - char ib = FlGui::instance()->selectEntity(what); - if(ib == 'l') { - if(CTX::instance()->pickElements){ - for(unsigned int i = 0; i < FlGui::instance()->selectedElements.size(); i++){ - if(FlGui::instance()->selectedElements[i]->getVisibility() != 2){ - FlGui::instance()->selectedElements[i]->setVisibility(2); - ele.push_back(FlGui::instance()->selectedElements[i]); - } - } - } - else{ - for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){ - if(FlGui::instance()->selectedEdges[i]->getSelection() != 1){ - FlGui::instance()->selectedEdges[i]->setSelection(1); - ent.push_back(FlGui::instance()->selectedEdges[i]); - } - } - for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++){ - if(FlGui::instance()->selectedFaces[i]->getSelection() != 1){ - FlGui::instance()->selectedFaces[i]->setSelection(1); - ent.push_back(FlGui::instance()->selectedFaces[i]); - } - } - for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++){ - if(FlGui::instance()->selectedRegions[i]->getSelection() != 1){ - FlGui::instance()->selectedRegions[i]->setSelection(1); - ent.push_back(FlGui::instance()->selectedRegions[i]); - } - } - } - } - if(ib == 'r') { - if(CTX::instance()->pickElements){ - for(unsigned int i = 0; i < FlGui::instance()->selectedElements.size(); i++) - FlGui::instance()->selectedElements[i]->setVisibility(1); - } - else{ - for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++) - FlGui::instance()->selectedEdges[i]->setSelection(0); - for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++) - FlGui::instance()->selectedFaces[i]->setSelection(0); - for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++) - FlGui::instance()->selectedRegions[i]->setSelection(0); - } - } - if(ib == 'u') { - if(CTX::instance()->pickElements){ - if(ele.size()){ - ele[ele.size() - 1]->setVisibility(1); - ele.pop_back(); - } - } - else{ - if(ent.size()){ - ent[ent.size() - 1]->setSelection(0); - ent.pop_back(); - } - } - } - if(ib == 'e') { - if(CTX::instance()->pickElements){ - for(unsigned int i = 0; i < ele.size(); i++) - if(ele[i]->getVisibility() == 2) ele[i]->setVisibility(0); - } - else{ - for(unsigned int i = 0; i < ent.size(); i++) - if(ent[i]->getSelection() == 1) ent[i]->setVisibility(0); - } - GModel::current()->removeInvisibleElements(); - ele.clear(); - ent.clear(); - } - if(ib == 'q') { - GModel::current()->setSelection(0); - break; - } - } - - CTX::instance()->mesh.changed = ENT_ALL; - CTX::instance()->pickElements = 0; - drawContext::global()->draw(); - Msg::StatusBar(3, false, ""); -} - -static std::vector<std::string> getInfoStrings(MElement *ele) -{ - std::vector<std::string> info; - { - std::ostringstream sstream; - sstream << "Element " << ele->getNum() << ":"; - info.push_back(sstream.str()); - } - { - std::ostringstream sstream; - const char *name; - MElement::getInfoMSH(ele->getTypeForMSH(), &name); - sstream << " " << name - << " (MSH type " << ele->getTypeForMSH() - << ", dimension "<< ele->getDim() - << ", order "<< ele->getPolynomialOrder() - << ", partition " << ele->getPartition() - << ")"; - info.push_back(sstream.str()); - } - { - std::ostringstream sstream; - sstream << " Vertices:"; - for(int i = 0; i < ele->getNumVertices(); i++) - sstream << " " << ele->getVertex(i)->getNum(); - info.push_back(sstream.str()); - } - { - std::ostringstream sstream; - SPoint3 pt = ele->barycenter(); - sstream << " Barycenter: (" << pt[0] << ", " << pt[1] << ", " << pt[2] << ")"; - info.push_back(sstream.str()); - } - { - std::ostringstream sstream; - sstream << " Quality: " - << "rho = " << ele->rhoShapeMeasure() << " " - << "gamma = " << ele->gammaShapeMeasure() << " " - << "eta = " << ele->etaShapeMeasure(); - info.push_back(sstream.str()); - } - { - std::ostringstream sstream; - double jmin, jmax; - ele->scaledJacRange(jmin, jmax); - sstream << " Scaled Jacobian range: " << jmin << " " << jmax; - info.push_back(sstream.str()); - } - { - std::ostringstream sstream; - sstream << " Inner / outer radius: " - << ele->getInnerRadius() << " / " << ele->getOuterRadius(); - info.push_back(sstream.str()); - } - return info; -} - -static void mesh_inspect_cb(Fl_Widget *w, void *data) -{ - CTX::instance()->pickElements = 1; - CTX::instance()->mesh.changed = ENT_ALL; - drawContext::global()->draw(); - - while(1) { - Msg::StatusBar(3, false, "Select element\n[Press 'q' to abort]"); - char ib = FlGui::instance()->selectEntity(ENT_ALL); - if(ib == 'l') { - if(FlGui::instance()->selectedElements.size()){ - MElement *ele = FlGui::instance()->selectedElements[0]; - GModel::current()->setSelection(0); - ele->setVisibility(2); - CTX::instance()->mesh.changed = ENT_ALL; - drawContext::global()->draw(); - std::vector<std::string> info = getInfoStrings(ele); - for(unsigned int i = 0; i < info.size(); i++) - Msg::Direct("%s", info[i].c_str()); - if(CTX::instance()->tooltips){ - std::string str; - for(unsigned int i = 0; i < info.size(); i++) - str += info[i] + "\n"; - FlGui::instance()->getCurrentOpenglWindow()->drawTooltip(str); - } - else - FlGui::instance()->showMessages(); - } - } - if(ib == 'q') { - GModel::current()->setSelection(0); - break; - } - } - - CTX::instance()->pickElements = 0; - CTX::instance()->mesh.changed = ENT_ALL; - drawContext::global()->draw(); - Msg::StatusBar(3, false, ""); -} - -static void mesh_change_order_cb(Fl_Widget *w, void *data) -{ - FlGui::instance()->menu->setContext(menu_mesh_degree, 0); -} - - -static void mesh_degree_cb(Fl_Widget *w, void *data) -{ - int degree = (intptr_t)data; - if(degree == 2) - SetOrderN(GModel::current(), 2, CTX::instance()->mesh.secondOrderLinear, - CTX::instance()->mesh.secondOrderIncomplete); - else if (degree == 1) - SetOrder1(GModel::current()); - else // For now, use the same options as for second order meshes - SetOrderN(GModel::current(), degree, - CTX::instance()->mesh.secondOrderLinear, - CTX::instance()->mesh.secondOrderIncomplete); - CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); - drawContext::global()->draw(); -} - -static void mesh_optimize_cb(Fl_Widget *w, void *data) -{ - if(CTX::instance()->lock) { - Msg::Info("I'm busy! Ask me that later..."); - return; - } - CTX::instance()->lock = 1; - OptimizeMesh(GModel::current()); - CTX::instance()->lock = 0; - CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); - drawContext::global()->draw(); -} - -static void mesh_refine_cb(Fl_Widget *w, void *data) -{ - RefineMesh(GModel::current(), CTX::instance()->mesh.secondOrderLinear); - CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); - drawContext::global()->draw(); -} - -static void mesh_optimize_netgen_cb(Fl_Widget *w, void *data) -{ - if(CTX::instance()->lock) { - Msg::Info("I'm busy! Ask me that later..."); - return; - } - CTX::instance()->lock = 1; - OptimizeMeshNetgen(GModel::current()); - CTX::instance()->lock = 0; - CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); - drawContext::global()->draw(); -} - -static void mesh_partition_cb(Fl_Widget *w, void *data) -{ - partition_dialog(); -} - -static void mesh_define_length_cb(Fl_Widget *w, void *data) -{ - action_point_line_surface_volume(8, 0, "Point"); -} - -static void mesh_define_recombine_cb(Fl_Widget *w, void *data) -{ - action_point_line_surface_volume(9, 0, "Surface"); -} - -static void mesh_define_transfinite_cb(Fl_Widget *w, void *data) -{ - FlGui::instance()->menu->setContext(menu_mesh_define_transfinite, 0); -} - -static void add_transfinite_embedded(int dim, bool embed) -{ - opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); - switch (dim) { - case 1: opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); break; - case 2: opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1); break; - case 3: opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1); break; - } - drawContext::global()->draw(); - - std::vector<int> p; - char ib; - while(1) { - switch (dim) { - case 1: - if(p.empty()) - Msg::StatusBar(3, false, "Select lines\n" - "[Press 'e' to end selection or 'q' to abort]"); - else - Msg::StatusBar(3, false, "Select lines\n" - "[Press 'e' to end selection, 'u' to undo last selection " - "or 'q' to abort]"); - ib = FlGui::instance()->selectEntity(ENT_LINE); - break; - case 2: - Msg::StatusBar(3, false, "Select surface\n[Press 'q' to abort]"); - ib = FlGui::instance()->selectEntity(ENT_SURFACE); - break; - case 3: - Msg::StatusBar(3, false, "Select volume\n[Press 'q' to abort]"); - ib = FlGui::instance()->selectEntity(ENT_VOLUME); - break; - default: - ib = 'l'; - break; - } - - if(ib == 'e') { - if(dim == 1) { - if(p.size()) - add_trsfline(p, GModel::current()->getFileName(), - FlGui::instance()->meshContext->choice[0]->text(), - FlGui::instance()->meshContext->input[2]->value(), - FlGui::instance()->meshContext->input[1]->value()); - } - GModel::current()->setSelection(0); - drawContext::global()->draw(); - p.clear(); - } - if(ib == 'u') { - if(dim == 1) { - if(p.size()){ - GEdge *ge = GModel::current()->getEdgeByTag(p.back()); - if(ge) ge->setSelection(0); - drawContext::global()->draw(); - p.pop_back(); - } - } - } - if(ib == 'q') { - GModel::current()->setSelection(0); - drawContext::global()->draw(); - break; - } - if(ib == 'r') { - Msg::Warning("Entity de-selection not supported yet during " - "transfinite definition"); - } - if(ib == 'l') { - switch (dim) { - case 1: - for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){ - FlGui::instance()->selectedEdges[i]->setSelection(1); - p.push_back(FlGui::instance()->selectedEdges[i]->tag()); - } - drawContext::global()->draw(); - break; - case 2: - case 3: - if(dim == 2){ - FlGui::instance()->selectedFaces[0]->setSelection(1); - drawContext::global()->draw(); - p.push_back(FlGui::instance()->selectedFaces[0]->tag()); - } - else{ - FlGui::instance()->selectedRegions[0]->setSelection(1); - drawContext::global()->draw(); - p.push_back(FlGui::instance()->selectedRegions[0]->tag()); - } - while(1) { - if(p.size() == 1) - Msg::StatusBar(3, false, "Select %s points\n" - "[Press 'e' to end selection or 'q' to abort]", - embed ? "embedded" : "(ordered) boundary"); - else - Msg::StatusBar(3, false, "Select %s points\n" - "[Press 'e' to end selection, 'u' to undo last selection " - "or 'q' to abort]", - embed ? "embedded" : "(ordered) boundary"); - ib = FlGui::instance()->selectEntity(ENT_POINT); - if(ib == 'l') { - for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){ - FlGui::instance()->selectedVertices[i]->setSelection(1); - p.push_back(FlGui::instance()->selectedVertices[i]->tag()); - if(!embed) break; - } - drawContext::global()->draw(); - } - if(ib == 'u') { - if(p.size() > 1){ - GVertex *gv = GModel::current()->getVertexByTag(p.back()); - if(gv) gv->setSelection(0); - drawContext::global()->draw(); - p.pop_back(); - } - } - if(ib == 'r') { - Msg::Warning("Entity de-selection not supported yet during " - "transfinite definition"); - } - if(ib == 'e') { - switch (dim) { - case 2: - if(embed && p.size()) - add_embedded("Point", p, GModel::current()->getFileName()); - else if(!embed && - (p.size() == 0 + 1 || p.size() == 3 + 1 || p.size() == 4 + 1)) - add_trsfsurf(p, GModel::current()->getFileName(), - FlGui::instance()->meshContext->choice[1]->text()); - else - Msg::Error("Wrong number of points for mesh constraint"); - break; - case 3: - if(p.size() == 6 + 1 || p.size() == 8 + 1) - add_trsfvol(p, GModel::current()->getFileName()); - else - Msg::Error("Wrong number of points for transfinite volume"); - break; - } - GModel::current()->setSelection(0); - drawContext::global()->draw(); - p.clear(); - break; - } - if(ib == 'q') { - GModel::current()->setSelection(0); - drawContext::global()->draw(); - goto stopall; - } - } - break; - } - } - } - - stopall: - Msg::StatusBar(3, false, ""); -} - -static void mesh_define_transfinite_line_cb(Fl_Widget *w, void *data) -{ - FlGui::instance()->meshContext->show(1); - add_transfinite_embedded(1, false); -} - -static void mesh_define_transfinite_surface_cb(Fl_Widget *w, void *data) -{ - FlGui::instance()->meshContext->show(2); - add_transfinite_embedded(2, false); -} - -static void mesh_define_transfinite_volume_cb(Fl_Widget *w, void *data) -{ - add_transfinite_embedded(3, false); -} - -static void mesh_define_embedded_cb(Fl_Widget *w, void *data) -{ - add_transfinite_embedded(2, true); -} - -static void mesh_define_compound_cb(Fl_Widget *w, void *data) -{ - FlGui::instance()->menu->setContext(menu_mesh_define_compound, 0); -} - -static void mesh_define_compound_entity_cb(Fl_Widget *w, void *data) -{ - action_point_line_surface_volume(10, 0, (const char *)data); -} - -static void view_toggle_cb(Fl_Widget *w, void *data) -{ - int num = (intptr_t)data; - opt_view_visible(num, GMSH_SET, - FlGui::instance()->menu->toggle[num]->value()); - drawContext::global()->draw(); -} - -static void view_reload(int index) -{ - if(index >= 0 && index < (int)PView::list.size()){ - PView *p = PView::list[index]; - - if(StatFile(p->getData()->getFileName())){ - Msg::Error("File '%s' does not exist", p->getData()->getFileName().c_str()); - return; - } - - int n = PView::list.size(); - - // FIXME: use fileIndex - MergeFile(p->getData()->getFileName()); - - if((int)PView::list.size() > n){ // we loaded a new view - // delete old data and replace with new - delete p->getData(); - p->setData(PView::list.back()->getData()); - PView::list.back()->setData(0); - // delete new view - delete PView::list.back(); - // in case the reloaded view has a different number of time steps - if(p->getOptions()->timeStep > p->getData()->getNumTimeSteps() - 1) - p->getOptions()->timeStep = 0; - p->setChanged(true); - FlGui::instance()->updateViews(); - } - } -} - -static void view_reload_cb(Fl_Widget *w, void *data) -{ - view_reload((intptr_t)data); - drawContext::global()->draw(); -} - -static void view_reload_all_cb(Fl_Widget *w, void *data) -{ - for(unsigned int i = 0; i < PView::list.size(); i++) - view_reload(i); - drawContext::global()->draw(); -} - -static void view_reload_visible_cb(Fl_Widget *w, void *data) -{ - for(unsigned int i = 0; i < PView::list.size(); i++) - if(opt_view_visible(i, GMSH_GET, 0)) - view_reload(i); - drawContext::global()->draw(); -} - -static void view_remove_other_cb(Fl_Widget *w, void *data) -{ - if(PView::list.empty()) return; - for(int i = PView::list.size() - 1; i >= 0; i--) - if(i != (intptr_t)data) delete PView::list[i]; - FlGui::instance()->updateViews(); - drawContext::global()->draw(); -} - -static void view_remove_all_cb(Fl_Widget *w, void *data) -{ - if(PView::list.empty()) return; - int mode = (intptr_t)data; - if(mode == -1){ // remove all - if(PView::list.empty()) return; - while(PView::list.size()) delete PView::list[0]; - } - else if(mode == -2){ // remove all visible - for(int i = PView::list.size() - 1; i >= 0; i--) - if(opt_view_visible(i, GMSH_GET, 0)) delete PView::list[i]; - } - else if(mode == -3){ // remove all invisible - for(int i = PView::list.size() - 1; i >= 0; i--) - if(!opt_view_visible(i, GMSH_GET, 0)) delete PView::list[i]; - } - else if(mode == -4){ // remove all empty - for(int i = PView::list.size() - 1; i >= 0; i--) - if(PView::list[i]->getData()->empty()) delete PView::list[i]; - } - else if(mode >=0 && mode < (int)PView::list.size()){ // remove by name - std::string name = PView::list[mode]->getData()->getName(); - for(int i = PView::list.size() - 1; i >= 0; i--) - if(PView::list[i]->getData()->getName() == name) delete PView::list[i]; - } - - FlGui::instance()->updateViews(); - drawContext::global()->draw(); -} - -static void view_remove_cb(Fl_Widget *w, void *data) -{ - delete PView::list[(intptr_t)data]; - FlGui::instance()->updateViews(); - drawContext::global()->draw(); -} - -static void view_save_cb(Fl_Widget *w, void *data) -{ - static const char *formats = - "Gmsh Parsed" TT "*.pos" NN - "Gmsh Mesh-based" TT "*.pos" NN - "Gmsh Legacy ASCII" TT "*.pos" NN - "Gmsh Legacy Binary" TT "*.pos" NN - "MED" TT "*.rmed" NN - "STL Surface" TT "*.stl" NN - "Generic TXT" TT "*.txt" NN; - - PView *view = PView::list[(intptr_t)data]; - test: - if(fileChooser(FILE_CHOOSER_CREATE, "Save As", formats, - view->getData()->getFileName().c_str())){ - std::string name = fileChooserGetName(1); - if(CTX::instance()->confirmOverwrite) { - if(!StatFile(name)) - if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", - "Cancel", "Replace", 0, name.c_str())) - goto test; - } - int format = 0; - switch(fileChooserGetFilter()){ - case 0: format = 2; break; - case 1: format = 5; break; - case 2: format = 0; break; - case 3: format = 1; break; - case 4: format = 6; break; - case 5: format = 3; break; - case 6: format = 4; break; - } - view->write(name, format); - } -} - -#undef TT -#undef NN - -static void view_alias_cb(Fl_Widget *w, void *data) -{ - new PView(PView::list[(intptr_t)data], false); - FlGui::instance()->updateViews(); - drawContext::global()->draw(); -} - -static void view_alias_with_options_cb(Fl_Widget *w, void *data) -{ - new PView(PView::list[(intptr_t)data], true); - FlGui::instance()->updateViews(); - drawContext::global()->draw(); -} - -static void view_combine_space_all_cb(Fl_Widget *w, void *data) -{ - PView::combine(false, 1, CTX::instance()->post.combineRemoveOrig); - FlGui::instance()->updateViews(); - drawContext::global()->draw(); -} - -static void view_combine_space_visible_cb(Fl_Widget *w, void *data) -{ - PView::combine(false, 0, CTX::instance()->post.combineRemoveOrig); - FlGui::instance()->updateViews(); - drawContext::global()->draw(); -} - -static void view_combine_space_by_name_cb(Fl_Widget *w, void *data) -{ - PView::combine(false, 2, CTX::instance()->post.combineRemoveOrig); - FlGui::instance()->updateViews(); - drawContext::global()->draw(); -} - -static void view_combine_time_all_cb(Fl_Widget *w, void *data) -{ - PView::combine(true, 1, CTX::instance()->post.combineRemoveOrig); - FlGui::instance()->updateViews(); - drawContext::global()->draw(); -} - -static void view_combine_time_visible_cb(Fl_Widget *w, void *data) -{ - PView::combine(true, 0, CTX::instance()->post.combineRemoveOrig); - FlGui::instance()->updateViews(); - drawContext::global()->draw(); -} - -static void view_combine_time_by_name_cb(Fl_Widget *w, void *data) -{ - PView::combine(true, 2, CTX::instance()->post.combineRemoveOrig); - FlGui::instance()->updateViews(); - drawContext::global()->draw(); -} - -static void view_all_visible_cb(Fl_Widget *w, void *data) -{ - int mode = (intptr_t)data; - std::string name; - if(mode >= 0) name = PView::list[mode]->getData()->getName(); - for(unsigned int i = 0; i < PView::list.size(); i++) - opt_view_visible(i, GMSH_SET | GMSH_GUI, - (mode == -1) ? 1 : - (mode == -2) ? 0 : - (mode == -3) ? !opt_view_visible(i, GMSH_GET, 0) : - (name == PView::list[i]->getData()->getName()) ? 1 : - 0); - drawContext::global()->draw(); -} - -static void view_applybgmesh_cb(Fl_Widget *w, void *data) -{ - int index = (intptr_t)data; - if(index >= 0 && index < (int)PView::list.size()) - GModel::current()->getFields()->setBackgroundMesh(index); -} - -// The static menus (we cannot use the 'g', 'm' 's' and 'p' mnemonics -// since they are already defined as global shortcuts) -static Fl_Menu_Item bar_table[] = { - {"&File", 0, 0, 0, FL_SUBMENU}, - {"&New...", FL_CTRL+'n', (Fl_Callback *)file_new_cb, 0}, - {"&Open...", FL_CTRL+'o', (Fl_Callback *)file_open_cb, 0}, - {"Open Recent", 0, 0, 0, FL_SUBMENU}, - {"", 0, (Fl_Callback *)file_open_recent_cb, 0}, - {"", 0, (Fl_Callback *)file_open_recent_cb, 0}, - {"", 0, (Fl_Callback *)file_open_recent_cb, 0}, - {"", 0, (Fl_Callback *)file_open_recent_cb, 0}, - {"", 0, (Fl_Callback *)file_open_recent_cb, 0}, - {0}, - {"M&erge...", FL_CTRL+FL_SHIFT+'o', (Fl_Callback *)file_merge_cb, 0}, - {"Watch Pattern...", 0, (Fl_Callback *)file_watch_cb, 0}, - {"&Clear", 0, (Fl_Callback *)file_clear_cb, 0, FL_MENU_DIVIDER}, -#if defined(HAVE_ONELAB) - {"Remote", 0, 0, 0, FL_MENU_DIVIDER | FL_SUBMENU}, - {"Start...", 0, (Fl_Callback *)file_remote_cb, (void*)"start"}, - {"Merge...", 0, (Fl_Callback *)file_remote_cb, (void*)"merge"}, - {"Clear", 0, (Fl_Callback *)file_remote_cb, (void*)"clear"}, - {"Stop", 0, (Fl_Callback *)file_remote_cb, (void*)"stop"}, - {0}, -#endif - {"New Window", 0, (Fl_Callback *)file_window_cb, (void*)"new"}, - {"Split Window", 0, 0, 0, FL_MENU_DIVIDER | FL_SUBMENU}, - {"Horizontally", 0, (Fl_Callback *)file_window_cb, (void*)"split_h"}, - {"Vertically", 0, (Fl_Callback *)file_window_cb, (void*)"split_v"}, - {"Clear", 0, (Fl_Callback *)file_window_cb, (void*)"split_u"}, - {0}, - {"&Rename...", FL_CTRL+'r', (Fl_Callback *)file_rename_cb, 0}, - {"Save &As...", FL_CTRL+'s', (Fl_Callback *)file_save_as_cb, 0}, - {"Sa&ve Mesh", FL_CTRL+FL_SHIFT+'s', (Fl_Callback *)mesh_save_cb, 0}, - {"Save Options", 0, 0, 0, FL_SUBMENU | FL_MENU_DIVIDER}, - {"For Current File", 0, (Fl_Callback *)file_options_save_cb, (void*)"file"}, - {"As Default", 0, (Fl_Callback *)file_options_save_cb, (void*)"default"}, - {0}, - {"&Quit", FL_CTRL+'q', (Fl_Callback *)file_quit_cb, 0}, - {0}, - {"&Tools", 0, 0, 0, FL_SUBMENU}, - {"&Options", FL_CTRL+FL_SHIFT+'n', (Fl_Callback *)options_cb, 0}, - {"Pl&ugins", FL_CTRL+FL_SHIFT+'u', (Fl_Callback *)plugin_cb, (void*)(-1)}, - {"&Visibility", FL_CTRL+FL_SHIFT+'v', (Fl_Callback *)visibility_cb, 0}, - {"&Clipping", FL_CTRL+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0}, - {"&Manipulator", FL_CTRL+FL_SHIFT+'m', (Fl_Callback *)manip_cb, 0}, -#if defined(HAVE_ONELAB) - {"&OneLab", 0, (Fl_Callback *)solver_cb, (void*)(-1), FL_MENU_DIVIDER}, -#endif -#if defined(HAVE_3M) - {"&3M", 0, (Fl_Callback *)window3M_cb, 0, FL_MENU_DIVIDER}, -#endif - {"S&tatistics", FL_CTRL+'i', (Fl_Callback *)statistics_cb, 0}, - {"M&essage Console", FL_CTRL+'l', (Fl_Callback *)message_cb, 0}, - {0}, - {"&Help", 0, 0, 0, FL_SUBMENU}, - {"On&line Documentation", 0, (Fl_Callback *)help_online_cb, 0, FL_MENU_DIVIDER}, - {"M&ouse Actions", 0, (Fl_Callback *)help_mouse_cb, 0}, - {"&Keyboard Shortcuts", 0, (Fl_Callback *)help_short_cb, 0}, - {"C&ommand Line Options", 0, (Fl_Callback *)help_command_line_cb, 0}, - {"&Current Options", 0, (Fl_Callback *)status_options_cb, (void*)"?", FL_MENU_DIVIDER}, - {"&About Gmsh", 0, (Fl_Callback *)help_about_cb, 0}, - {0}, - {0} -}; - -#if defined(__APPLE__) - -// Alternative items for the MacOS system menu bar (removed '&' -// shortcuts: they would cause spurious menu items to appear on the -// menu window; removed File->Quit) -static Fl_Menu_Item sysbar_table[] = { - {"File", 0, 0, 0, FL_SUBMENU}, - {"New...", FL_META+'n', (Fl_Callback *)file_new_cb, 0}, - {"Open...", FL_META+'o', (Fl_Callback *)file_open_cb, 0}, - // system menu bar is not dynamic in fltk 1.1; it is in fltk 1.3 -#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3) - {"Open Recent", 0, 0, 0, FL_SUBMENU}, - {"", 0, (Fl_Callback *)file_open_recent_cb, 0}, - {"", 0, (Fl_Callback *)file_open_recent_cb, 0}, - {"", 0, (Fl_Callback *)file_open_recent_cb, 0}, - {"", 0, (Fl_Callback *)file_open_recent_cb, 0}, - {"", 0, (Fl_Callback *)file_open_recent_cb, 0}, - {0}, -#endif - {"Merge...", FL_META+FL_SHIFT+'o', (Fl_Callback *)file_merge_cb, 0}, - {"Watch Pattern...", 0, (Fl_Callback *)file_watch_cb, 0}, - {"Clear", 0, (Fl_Callback *)file_clear_cb, 0, FL_MENU_DIVIDER}, - {"Remote", 0, 0, 0, FL_MENU_DIVIDER | FL_SUBMENU}, - {"Start...", 0, (Fl_Callback *)file_remote_cb, (void*)"start"}, - {"Merge...", 0, (Fl_Callback *)file_remote_cb, (void*)"merge"}, - {"Clear", 0, (Fl_Callback *)file_remote_cb, (void*)"clear"}, - {"Stop", 0, (Fl_Callback *)file_remote_cb, (void*)"stop"}, - {0}, - {"New Window", 0, (Fl_Callback *)file_window_cb, (void*)"new"}, - {"Split Window", 0, 0, 0, FL_MENU_DIVIDER | FL_SUBMENU}, - {"Horizontally", 0, (Fl_Callback *)file_window_cb, (void*)"split_h"}, - {"Vertically", 0, (Fl_Callback *)file_window_cb, (void*)"split_v"}, - {"Clear", 0, (Fl_Callback *)file_window_cb, (void*)"split_u"}, - {0}, - {"Rename...", FL_META+'r', (Fl_Callback *)file_rename_cb, 0}, - {"Save As...", FL_META+'s', (Fl_Callback *)file_save_as_cb, 0}, - {"Save Mesh", FL_META+FL_SHIFT+'s', (Fl_Callback *)mesh_save_cb, 0}, - {"Save Options", 0, 0, 0, FL_SUBMENU}, - {"For Current File", 0, (Fl_Callback *)file_options_save_cb, (void*)"file"}, - {"As Default", 0, (Fl_Callback *)file_options_save_cb, (void*)"default"}, - {0}, - {0}, - {"Tools", 0, 0, 0, FL_SUBMENU}, - {"Options", FL_META+FL_SHIFT+'n', (Fl_Callback *)options_cb, 0}, - {"Plugins", FL_META+FL_SHIFT+'u', (Fl_Callback *)plugin_cb, (void*)(-1)}, - {"Visibility", FL_META+FL_SHIFT+'v', (Fl_Callback *)visibility_cb, 0}, - {"Clipping", FL_META+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0}, - {"Manipulator", FL_META+FL_SHIFT+'m', (Fl_Callback *)manip_cb, 0}, -#if defined(HAVE_ONELAB) - {"OneLab", 0, (Fl_Callback *)solver_cb, (void*)(-1), FL_MENU_DIVIDER}, -#endif -#if defined(HAVE_3M) - {"3M", 0, (Fl_Callback *)window3M_cb, 0, FL_MENU_DIVIDER}, -#endif - {"Statistics", FL_META+'i', (Fl_Callback *)statistics_cb, 0}, - {"Message Console", FL_META+'l', (Fl_Callback *)message_cb, 0}, - {0}, - {"Window", 0, 0, 0, FL_SUBMENU}, - {"Minimize", FL_META+'m', (Fl_Callback *)window_cb, (void*)"minimize"}, - {"Zoom", 0, (Fl_Callback *)window_cb, (void*)"zoom", FL_MENU_DIVIDER}, - {"Bring All to Front", 0, (Fl_Callback *)window_cb, (void*)"front"}, - {0}, - {"Help", 0, 0, 0, FL_SUBMENU}, - {"Online Documentation", 0, (Fl_Callback *)help_online_cb, 0, FL_MENU_DIVIDER}, - {"Mouse Actions", 0, (Fl_Callback *)help_mouse_cb, 0}, - {"Keyboard Shortcuts", 0, (Fl_Callback *)help_short_cb, 0}, - {"Command Line Options", 0, (Fl_Callback *)help_command_line_cb, 0}, -#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3) - {"Current Options", 0, (Fl_Callback *)status_options_cb, (void*)"?"}, -#else - {"Current Options", 0, (Fl_Callback *)status_options_cb, (void*)"?", FL_MENU_DIVIDER}, - {"About Gmsh", 0, (Fl_Callback *)help_about_cb, 0}, -#endif - {0}, - {0} -}; - -#endif - -static Fl_Menu_Item module_table[] = { - {"Geometry", 'g', (Fl_Callback *)mod_geometry_cb, 0}, - {"Mesh", 'm', (Fl_Callback *)mod_mesh_cb, 0}, - {"Solver", 's', (Fl_Callback *)mod_solver_cb, 0}, - {"Post-processing", 'p', (Fl_Callback *)mod_post_cb, 0}, - {0} -}; - -// Dynamic menus contexts -contextItem menu_geometry[] = { - {"0Geometry"} , - {"Elementary entities", (Fl_Callback *)geometry_elementary_cb} , - {"Physical groups", (Fl_Callback *)geometry_physical_cb} , - {"Edit", (Fl_Callback *)geometry_edit_cb} , - {"Reload", (Fl_Callback *)geometry_reload_cb} , - {""} -}; - contextItem menu_geometry_elementary[] = { - {"0Geometry>Elementary"} , - {"Add", (Fl_Callback *)geometry_elementary_add_cb} , - {"Delete", (Fl_Callback *)geometry_elementary_delete_cb, (void*)0} , - {"Translate", (Fl_Callback *)geometry_elementary_translate_cb, (void*)0} , - {"Rotate", (Fl_Callback *)geometry_elementary_rotate_cb, (void*)0} , - {"Split", (Fl_Callback *)geometry_elementary_split_cb, (void*)0} , - {"Scale", (Fl_Callback *)geometry_elementary_scale_cb, (void*)0} , - {"Symmetry", (Fl_Callback *)geometry_elementary_symmetry_cb, (void*)0} , - {"Extrude", (Fl_Callback *)geometry_elementary_extrude_cb, (void*)0} , - {"Coherence", (Fl_Callback *)geometry_elementary_coherence_cb} , - {""} - }; - contextItem menu_geometry_elementary_add[] = { - {"0Geometry>Elementary>Add"} , - {"New", (Fl_Callback *)geometry_elementary_add_new_cb, (void*)0} , - {"Translate", (Fl_Callback *)geometry_elementary_add_translate_cb, (void*)0} , - {"Rotate", (Fl_Callback *)geometry_elementary_add_rotate_cb, (void*)0} , - {"Scale", (Fl_Callback *)geometry_elementary_add_scale_cb, (void*)0} , - {"Symmetry", (Fl_Callback *)geometry_elementary_add_symmetry_cb, (void*)0} , - {""} - }; - contextItem menu_geometry_elementary_add_new[] = { - {"0Geometry>Elementary>Add>New"} , - {"Parameter", (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Parameter"} , - {"Point", (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Point"} , - {"Straight line", (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Line"} , - {"Spline", (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Spline"} , - {"B-Spline", (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"BSpline"} , - {"Circle arc", (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Circle"} , - {"Ellipse arc", (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Ellipse"} , - {"Plane surface", (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Plane Surface"} , - {"Ruled surface", (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Ruled Surface"} , - {"Volume", (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Volume"} , - {""} - }; - contextItem menu_geometry_elementary_add_translate[] = { - {"0Geometry>Elementary>Add>Translate"} , - {"Point", (Fl_Callback *)geometry_elementary_add_translate_cb, (void*)"Point"} , - {"Line", (Fl_Callback *)geometry_elementary_add_translate_cb, (void*)"Line"} , - {"Surface", (Fl_Callback *)geometry_elementary_add_translate_cb, (void*)"Surface"} , - {"Volume", (Fl_Callback *)geometry_elementary_add_translate_cb, (void*)"Volume"} , - {""} - }; - contextItem menu_geometry_elementary_add_rotate[] = { - {"0Geometry>Elementary>Add>Rotate"} , - {"Point", (Fl_Callback *)geometry_elementary_add_rotate_cb, (void*)"Point"} , - {"Line", (Fl_Callback *)geometry_elementary_add_rotate_cb, (void*)"Line"} , - {"Surface", (Fl_Callback *)geometry_elementary_add_rotate_cb, (void*)"Surface"} , - {"Volume", (Fl_Callback *)geometry_elementary_add_rotate_cb, (void*)"Volume"} , - {""} - }; - contextItem menu_geometry_elementary_add_scale[] = { - {"0Geometry>Elementary>Add>Scale"} , - {"Point", (Fl_Callback *)geometry_elementary_add_scale_cb, (void*)"Point"} , - {"Line", (Fl_Callback *)geometry_elementary_add_scale_cb, (void*)"Line"} , - {"Surface", (Fl_Callback *)geometry_elementary_add_scale_cb, (void*)"Surface"} , - {"Volume", (Fl_Callback *)geometry_elementary_add_scale_cb, (void*)"Volume"} , - {""} - }; - contextItem menu_geometry_elementary_add_symmetry[] = { - {"0Geometry>Elementary>Add>Symmetry"} , - {"Point", (Fl_Callback *)geometry_elementary_add_symmetry_cb, (void*)"Point"} , - {"Line", (Fl_Callback *)geometry_elementary_add_symmetry_cb, (void*)"Line"} , - {"Surface", (Fl_Callback *)geometry_elementary_add_symmetry_cb, (void*)"Surface"} , - {"Volume", (Fl_Callback *)geometry_elementary_add_symmetry_cb, (void*)"Volume"} , - {""} - }; - contextItem menu_geometry_elementary_delete[] = { - {"0Geometry>Elementary>Delete"} , - {"Point", (Fl_Callback *)geometry_elementary_delete_cb, (void*)"Point"} , - {"Line", (Fl_Callback *)geometry_elementary_delete_cb, (void*)"Line"} , - {"Surface", (Fl_Callback *)geometry_elementary_delete_cb, (void*)"Surface"} , - {"Volume", (Fl_Callback *)geometry_elementary_delete_cb, (void*)"Volume"} , - {""} - }; - contextItem menu_geometry_elementary_split[] = { - {"0Geometry>Elementary>Split"}, - {"Line",(Fl_Callback *)geometry_elementary_split_cb,(void*)"Line"}, - {""} - }; - contextItem menu_geometry_elementary_translate[] = { - {"0Geometry>Elementary>Translate"} , - {"Point", (Fl_Callback *)geometry_elementary_translate_cb, (void*)"Point"} , - {"Line", (Fl_Callback *)geometry_elementary_translate_cb, (void*)"Line"} , - {"Surface", (Fl_Callback *)geometry_elementary_translate_cb, (void*)"Surface"} , - {"Volume", (Fl_Callback *)geometry_elementary_translate_cb, (void*)"Volume"} , - {""} - }; - contextItem menu_geometry_elementary_rotate[] = { - {"0Geometry>Elementary>Rotate"} , - {"Point", (Fl_Callback *)geometry_elementary_rotate_cb, (void*)"Point"} , - {"Line", (Fl_Callback *)geometry_elementary_rotate_cb, (void*)"Line"} , - {"Surface", (Fl_Callback *)geometry_elementary_rotate_cb, (void*)"Surface"} , - {"Volume", (Fl_Callback *)geometry_elementary_rotate_cb, (void*)"Volume"} , - {""} - }; - contextItem menu_geometry_elementary_scale[] = { - {"0Geometry>Elementary>Scale"} , - {"Point", (Fl_Callback *)geometry_elementary_scale_cb, (void*)"Point"} , - {"Line", (Fl_Callback *)geometry_elementary_scale_cb, (void*)"Line"} , - {"Surface", (Fl_Callback *)geometry_elementary_scale_cb, (void*)"Surface"} , - {"Volume", (Fl_Callback *)geometry_elementary_scale_cb, (void*)"Volume"} , - {""} - }; - contextItem menu_geometry_elementary_symmetry[] = { - {"0Geometry>Elementary>Symmetry"} , - {"Point", (Fl_Callback *)geometry_elementary_symmetry_cb, (void*)"Point"} , - {"Line", (Fl_Callback *)geometry_elementary_symmetry_cb, (void*)"Line"} , - {"Surface", (Fl_Callback *)geometry_elementary_symmetry_cb, (void*)"Surface"} , - {"Volume", (Fl_Callback *)geometry_elementary_symmetry_cb, (void*)"Volume"} , - {""} - }; - contextItem menu_geometry_elementary_extrude[] = { - {"0Geometry>Elementary>Extrude"} , - {"Translate", (Fl_Callback *)geometry_elementary_extrude_translate_cb, (void*)0} , - {"Rotate", (Fl_Callback *)geometry_elementary_extrude_rotate_cb, (void*)0} , - {""} - }; - contextItem menu_geometry_elementary_extrude_translate[] = { - {"0Geometry>Elementary>Extrude>Translate"} , - {"Point", (Fl_Callback *)geometry_elementary_extrude_translate_cb, (void*)"Point"} , - {"Line", (Fl_Callback *)geometry_elementary_extrude_translate_cb, (void*)"Line"} , - {"Surface", (Fl_Callback *)geometry_elementary_extrude_translate_cb, (void*)"Surface"} , - {""} - }; - contextItem menu_geometry_elementary_extrude_rotate[] = { - {"0Geometry>Elementary>Extrude>Rotate"} , - {"Point", (Fl_Callback *)geometry_elementary_extrude_rotate_cb, (void*)"Point"} , - {"Line", (Fl_Callback *)geometry_elementary_extrude_rotate_cb, (void*)"Line"} , - {"Surface", (Fl_Callback *)geometry_elementary_extrude_rotate_cb, (void*)"Surface"} , - {""} - }; - contextItem menu_geometry_physical[] = { - {"0Geometry>Physical"} , - {"Add", (Fl_Callback *)geometry_physical_add_cb, (void*)0} , - {""} - }; - contextItem menu_geometry_physical_add[] = { - {"0Geometry>Physical>Add"} , - {"Point", (Fl_Callback *)geometry_physical_add_cb, (void*)"Point" } , - {"Line", (Fl_Callback *)geometry_physical_add_cb, (void*)"Line" } , - {"Surface", (Fl_Callback *)geometry_physical_add_cb, (void*)"Surface" } , - {"Volume", (Fl_Callback *)geometry_physical_add_cb, (void*)"Volume" } , - {""} - }; - -contextItem menu_mesh[] = { - {"1Mesh"} , - {"Define", (Fl_Callback *)mesh_define_cb} , - {"1D", (Fl_Callback *)mesh_1d_cb} , - {"2D", (Fl_Callback *)mesh_2d_cb} , - {"3D", (Fl_Callback *)mesh_3d_cb} , - {"Optimize 3D", (Fl_Callback *)mesh_optimize_cb} , -#if defined(HAVE_NETGEN) - {"Optimize 3D (Netgen)", (Fl_Callback *)mesh_optimize_netgen_cb} , -#endif - {"Set order", (Fl_Callback *)mesh_change_order_cb} , - {"Inspect", (Fl_Callback *)mesh_inspect_cb} , - {"Refine by splitting", (Fl_Callback *)mesh_refine_cb} , -#if defined(HAVE_METIS) || defined(HAVE_CHACO) - {"Partition", (Fl_Callback *)mesh_partition_cb} , -#endif - {"Reclassify 2D", (Fl_Callback *)mesh_classify_cb} , -#if defined(HAVE_FOURIER_MODEL) - {"Reparameterize 2D", (Fl_Callback *)mesh_parameterize_cb} , -#endif - {"Delete", (Fl_Callback *)mesh_delete_cb} , - {"Save", (Fl_Callback *)mesh_save_cb} , - {""} -}; - contextItem menu_mesh_define[] = { - {"1Mesh>Define"} , - {"Size fields", (Fl_Callback *)field_cb}, - {"Element size at points", (Fl_Callback *)mesh_define_length_cb } , - {"Embedded points", (Fl_Callback *)mesh_define_embedded_cb, (void*)"point" } , - {"Recombine", (Fl_Callback *)mesh_define_recombine_cb } , - {"Transfinite", (Fl_Callback *)mesh_define_transfinite_cb } , - {"Compound", (Fl_Callback *)mesh_define_compound_cb } , - {""} - }; - contextItem menu_mesh_define_transfinite[] = { - {"1Mesh>Define>Transfinite"} , - {"Line", (Fl_Callback *)mesh_define_transfinite_line_cb} , - {"Surface", (Fl_Callback *)mesh_define_transfinite_surface_cb} , - {"Volume", (Fl_Callback *)mesh_define_transfinite_volume_cb} , - {""} - }; - contextItem menu_mesh_define_compound[] = { - {"1Mesh>Define>Compound"} , - {"Line", (Fl_Callback *)mesh_define_compound_entity_cb, (void*)"Line"} , - {"Surface", (Fl_Callback *)mesh_define_compound_entity_cb, (void*)"Surface"} , - {"Volume", (Fl_Callback *)mesh_define_compound_entity_cb, (void*)"Volume"} , - {""} - }; - contextItem menu_mesh_delete[] = { - {"1Mesh>Edit>Delete"} , - {"Elements", (Fl_Callback *)mesh_delete_parts_cb, (void*)"elements"} , - {"Lines", (Fl_Callback *)mesh_delete_parts_cb, (void*)"lines"} , - {"Surfaces", (Fl_Callback *)mesh_delete_parts_cb, (void*)"surfaces"} , - {"Volumes", (Fl_Callback *)mesh_delete_parts_cb, (void*)"volumes"} , - {""} - }; - contextItem menu_mesh_degree[] = { - {"1Mesh>Set order"} , - {"1", (Fl_Callback *)mesh_degree_cb, (void*)1}, - {"2", (Fl_Callback *)mesh_degree_cb, (void*)2}, - {"3", (Fl_Callback *)mesh_degree_cb, (void*)3}, - {"4", (Fl_Callback *)mesh_degree_cb, (void*)4}, - {"5", (Fl_Callback *)mesh_degree_cb, (void*)5}, - {"Optimize", (Fl_Callback *)highordertools_cb}, - {""} - }; - -contextItem menu_solver[] = { - {"2Solver"} , - {"Solver 0", (Fl_Callback *)solver_cb , (void*)0} , - {"Solver 1", (Fl_Callback *)solver_cb , (void*)1} , - {"Solver 2", (Fl_Callback *)solver_cb , (void*)2} , - {"Solver 3", (Fl_Callback *)solver_cb , (void*)3} , - {"Solver 4", (Fl_Callback *)solver_cb , (void*)4} , - {""} -}; - -contextItem menu_post[] = { - {"3Post-processing"} , - {""} -}; - -menuWindow::menuWindow() -{ - int width = 14 * FL_NORMAL_SIZE; - - // this is the initial height: no dynamic button is shown -#if defined(__APPLE__) - if(CTX::instance()->systemMenuBar){ - _MH = BH + 6; // the menu bar is not in the application - } - else{ -#endif - _MH = BH + BH + 6; -#if defined(__APPLE__) - } -#endif - - win = new mainWindow - (width, _MH + NB_BUTT_SCROLL * BH, CTX::instance()->nonModalWindows ? - true : false, "Gmsh"); - win->box(GMSH_WINDOW_BOX); - win->callback(file_quit_cb); - - int y; -#if defined(__APPLE__) - if(CTX::instance()->systemMenuBar){ - // the system menubar is kind of a hack in fltk < 1.1.7: it still - // creates a real (invisible) menubar. To avoid spurious mouse - // click events we make it a 1x1 pixel rectangle, 1 pixel off the - // edge (so it falls behind the navigation buttons) - sysbar = new Fl_Sys_Menu_Bar(1, 1, 1, 1); - sysbar->menu(sysbar_table); - sysbar->global(); - fillRecentHistoryMenu(); - Fl_Box *o = new Fl_Box(0, 0, width, BH + 6); - o->box(FL_UP_BOX); - y = 3; - } - else{ -#endif - bar = new Fl_Menu_Bar(0, 0, width, BH); - bar->menu(bar_table); - bar->box(FL_UP_BOX); - bar->global(); - fillRecentHistoryMenu(); - Fl_Box *o = new Fl_Box(0, BH, width, BH + 6); - o->box(FL_UP_BOX); - y = BH + 3; -#if defined(__APPLE__) - } -#endif - - navig[0] = new Fl_Button(1, y, 18, BH / 2, "@#-1<"); - navig[0]->labeltype(FL_SYMBOL_LABEL); - navig[0]->box(FL_FLAT_BOX); - navig[0]->selection_color(FL_WHITE); - navig[0]->callback(mod_back_cb); - navig[0]->tooltip("Go back one in the menu history (<)"); - - navig[1] = new Fl_Button(1, y + BH / 2, 18, BH / 2, "@#-1>"); - navig[1]->labeltype(FL_SYMBOL_LABEL); - navig[1]->box(FL_FLAT_BOX); - navig[1]->selection_color(FL_WHITE); - navig[1]->callback(mod_forward_cb); - navig[1]->tooltip("Go forward one in the menu history (>)"); - - module = new Fl_Choice(19, y, width - 24, BH); - module->menu(module_table); - module->box(FL_THIN_DOWN_BOX); - // force the executation of the callback even if we didn't change - // the selection (we want to go back to the top-level menu every - // time we select one of the categories, even if the category is not - // changed): - module->when(FL_WHEN_RELEASE_ALWAYS); - - // create an empty scroll area that will get populated dynamically - // in set_context() - scroll = new Fl_Scroll(0, _MH, width, NB_BUTT_SCROLL * BH); - scroll->type(Fl_Scroll::VERTICAL); - scroll->end(); - - win->size(width, _MH); - win->position(CTX::instance()->menuPosition[0], - CTX::instance()->menuPosition[1]); - - win->end(); -} - -void menuWindow::setContext(contextItem *menu_asked, int flag) -{ - static int nb_back = 0, nb_forward = 0, init_context = 0; - static contextItem *menu_history[NB_HISTORY_MAX]; - contextItem *menu; - - if(!init_context) { - init_context = 1; - for(int i = 0; i < NB_HISTORY_MAX; i++) { - menu_history[i] = 0; - } - } - - if(nb_back > NB_HISTORY_MAX - 2) - nb_back = 1; // we should do a circular list - - if(flag == -1) { - if(nb_back > 1) { - nb_back--; - nb_forward++; - menu = menu_history[nb_back - 1]; - } - else - return; - } - else if(flag == 1) { - if(nb_forward > 0) { - nb_back++; - nb_forward--; - menu = menu_history[nb_back - 1]; - } - else - return; - } - else if(menu_asked){ - menu = menu_asked; - if(!nb_back || menu_history[nb_back - 1] != menu) { - menu_history[nb_back++] = menu; - } - nb_forward = 0; - } - else{ - Msg::Warning("No menu asked..."); - return; - } - - if(menu[0].label[0] == '0'){ - module->value(0); - } - else if(menu[0].label[0] == '1'){ - module->value(1); - } - else if(menu[0].label[0] == '2'){ - module->value(2); - menu[1].label = opt_solver_name0(0, GMSH_GET, ""); - menu[2].label = opt_solver_name1(0, GMSH_GET, ""); - menu[3].label = opt_solver_name2(0, GMSH_GET, ""); - menu[4].label = opt_solver_name3(0, GMSH_GET, ""); - menu[5].label = opt_solver_name4(0, GMSH_GET, ""); - } - else if(menu[0].label[0] == '3'){ - module->value(3); - } - else { - Msg::Warning("Something is wrong in dynamic menu definition"); - return; - } - - Msg::StatusBar(1, false, menu[0].label.c_str() + 1); - - // cannot use scroll->clear() in fltk 1.1 (should be fixed in 1.3) - for(unsigned int i = 0; i < push.size(); i++){ - scroll->remove(push[i]); - Fl::delete_widget(push[i]); - } - for(unsigned int i = 0; i < toggle.size(); i++){ - scroll->remove(toggle[i]); - Fl::delete_widget(toggle[i]); - } - for(unsigned int i = 0; i < toggle2.size(); i++){ - scroll->remove(toggle2[i]); - Fl::delete_widget(toggle2[i]); - } - for(unsigned int i = 0; i < popup.size(); i++){ - scroll->remove(popup[i]); - Fl::delete_widget(popup[i]); - } - for(unsigned int i = 0; i < popup2.size(); i++){ - scroll->remove(popup2[i]); - Fl::delete_widget(popup2[i]); - } - - // reset the vectors - push.clear(); - toggle.clear(); - toggle2.clear(); - popup.clear(); - popup2.clear(); - for(unsigned int i = 0; i < label.size(); i++) - delete [] label[i]; - label.clear(); - for(unsigned int i = 0; i < label2.size(); i++) - delete [] label2[i]; - label2.clear(); - - int width = win->w(); - int popw = 4 * FL_NORMAL_SIZE + 3; - - // construct the dynamic menu - int nb = 0; - if(module->value() == 3){ // post-processing context - for(nb = 0; nb < (int)PView::list.size(); nb++) { - PViewData *data = PView::list[nb]->getData(); - PViewOptions *opt = PView::list[nb]->getOptions(); - - Fl_Light_Button *b1 = new Fl_Light_Button(0, _MH + nb * BH, width - popw, BH); - b1->callback(view_toggle_cb, (void *)nb); - b1->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); - b1->value(opt->visible); - b1->copy_label(data->getName().c_str()); - char *tmp2 = new char[data->getFileName().size() + 1]; - strcpy(tmp2, data->getFileName().c_str()); - b1->tooltip(tmp2); - label2.push_back(tmp2); - - char *tmp = new char[32]; - sprintf(tmp, "[%d]@#-1>", nb); - Fl_Button *b2 = new Fl_Button(width - popw, _MH + nb * BH, popw, BH, tmp); - label.push_back(tmp); - b2->align(FL_ALIGN_RIGHT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); - b2->tooltip("Show view option menu (Shift+w)"); - - popupButton *p[2]; - p[0] = new popupButton(width - popw, _MH + nb * BH, popw, BH); - p[0]->type(Fl_Menu_Button::POPUP123); - p[1] = new popupButton(0, _MH + nb * BH, width - popw, BH); - p[1]->type(Fl_Menu_Button::POPUP3); - - for(int j = 0; j < 2; j++) { - p[j]->add("Reload/View", 'r', - (Fl_Callback *) view_reload_cb, (void *)nb, 0); - p[j]->add("Reload/Visible Views", 0, - (Fl_Callback *) view_reload_visible_cb, (void *)nb, 0); - p[j]->add("Reload/All Views", 0, - (Fl_Callback *) view_reload_all_cb, (void *)nb, 0); - p[j]->add("Remove/View", FL_Delete, - (Fl_Callback *) view_remove_cb, (void *)nb, 0); - p[j]->add("Remove/Other Views", 0, - (Fl_Callback *) view_remove_other_cb, (void *)nb, 0); - p[j]->add("Remove/Visible Views", 0, - (Fl_Callback *) view_remove_all_cb, (void *)-2, 0); - p[j]->add("Remove/Invisible Views", 0, - (Fl_Callback *) view_remove_all_cb, (void *)-3, 0); - p[j]->add("Remove/Empty Views", 0, - (Fl_Callback *) view_remove_all_cb, (void *)-4, 0); - p[j]->add("Remove/All Views", 0, - (Fl_Callback *) view_remove_all_cb, (void *)-1, 0); - p[j]->add("Remove/By Name", 0, - (Fl_Callback *) view_remove_all_cb, (void *)nb, 0); - p[j]->add("Alias/View without Options", 0, - (Fl_Callback *) view_alias_cb, (void *)nb, 0); - p[j]->add("Alias/View with Options", 0, - (Fl_Callback *) view_alias_with_options_cb, (void *)nb, 0); - p[j]->add("Combine Elements/From Visible Views", 0, - (Fl_Callback *) view_combine_space_visible_cb, (void *)nb, 0); - p[j]->add("Combine Elements/From All Views", 0, - (Fl_Callback *) view_combine_space_all_cb, (void *)nb, 0); - p[j]->add("Combine Elements/By View Name", 0, - (Fl_Callback *) view_combine_space_by_name_cb, (void *)nb, 0); - p[j]->add("Combine Time Steps/From Visible Views", 0, - (Fl_Callback *) view_combine_time_visible_cb, (void *)nb, 0); - p[j]->add("Combine Time Steps/From All Views", 0, - (Fl_Callback *) view_combine_time_all_cb, (void *)nb, 0); - p[j]->add("Combine Time Steps/By View Name", 0, - (Fl_Callback *) view_combine_time_by_name_cb, (void *)nb, 0); - p[j]->add("Set Visibility/All On", 0, - (Fl_Callback *) view_all_visible_cb, (void *)-1, 0); - p[j]->add("Set Visibility/All Off", 0, - (Fl_Callback *) view_all_visible_cb, (void *)-2, 0); - p[j]->add("Set Visibility/Invert", 0, - (Fl_Callback *) view_all_visible_cb, (void *)-3, 0); - p[j]->add("Set Visibility/By name", 0, - (Fl_Callback *) view_all_visible_cb, (void *)nb, 0); - p[j]->add("Apply As Background Mesh", 0, - (Fl_Callback *) view_applybgmesh_cb, (void *)nb, 0); - p[j]->add("Save As...", 0, - (Fl_Callback *) view_save_cb, (void *)nb, FL_MENU_DIVIDER); - p[j]->add("Options", 'o', - (Fl_Callback *) view_options_cb, (void *)nb, 0); - p[j]->add("Plugins", 'p', - (Fl_Callback *) plugin_cb, (void *)nb, 0); - } - - toggle.push_back(b1); - toggle2.push_back(b2); - popup.push_back(p[0]); - popup2.push_back(p[1]); - scroll->add(b1); - scroll->add(b2); - scroll->add(p[0]); - scroll->add(p[1]); - } - } - else{ // geometry, mesh and solver contexts - while(menu[nb + 1].label.size()) { - Fl_Button *b = new Fl_Button(0, _MH + nb * BH, width, BH); - b->copy_label(menu[nb + 1].label.c_str()); - b->callback(menu[nb + 1].callback, menu[nb + 1].arg); - push.push_back(b); - scroll->add(b); - nb++; - } - } - - /* scroll to the end of the list - int hh = (nb - NB_BUTT_SCROLL) * BH; - if(hh > 0) scroll->scroll_to(0, hh); - */ - - scroll->redraw(); - - if(nb <= NB_BUTT_SCROLL) - win->size(width, _MH + nb * BH); - else - win->size(width, _MH + NB_BUTT_SCROLL * BH); -} - -void menuWindow::fillRecentHistoryMenu() -{ - Fl_Menu_Item *table = bar_table; -#if defined(__APPLE__) && (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3) - if(CTX::instance()->systemMenuBar) - table = sysbar_table; -#endif - - for(int i = 0; i < 5; i++){ - table[4 + i].text = CTX::instance()->recentFiles[i].c_str(); - table[4 + i].user_data_ = (void*)CTX::instance()->recentFiles[i].c_str(); - } - -#if defined(__APPLE__) && (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3) - if(CTX::instance()->systemMenuBar) - sysbar->menu(table); -#endif -} diff --git a/Fltk/menuWindow.h b/Fltk/menuWindow.h deleted file mode 100644 index e3a82f2330a09a9634f1b929f335e01affda9437..0000000000000000000000000000000000000000 --- a/Fltk/menuWindow.h +++ /dev/null @@ -1,96 +0,0 @@ -// Gmsh - Copyright (C) 1997-2012 C. Geuzaine, J.-F. Remacle -// -// See the LICENSE.txt file for license information. Please report all -// bugs and problems to <gmsh@geuz.org>. - -#ifndef _MENU_WINDOW_H_ -#define _MENU_WINDOW_H_ - -#include <string> -#include <vector> -#include <FL/Fl_Window.H> -#if defined(__APPLE__) -#include <FL/Fl_Sys_Menu_Bar.H> -#endif -#include <FL/Fl_Menu_Bar.H> -#include <FL/Fl_Scroll.H> -#include <FL/Fl_Choice.H> -#include <FL/Fl_Button.H> -#include <FL/Fl_Light_Button.H> -#include "popupButton.h" - -// The dynamic menu contexts -typedef struct{ - std::string label; - Fl_Callback *callback; - void *arg; -} contextItem; - -extern contextItem menu_geometry[]; -extern contextItem menu_geometry_elementary[]; -extern contextItem menu_geometry_elementary_add[]; -extern contextItem menu_geometry_elementary_add_new[]; -extern contextItem menu_geometry_elementary_add_translate[]; -extern contextItem menu_geometry_elementary_add_rotate[]; -extern contextItem menu_geometry_elementary_add_scale[]; -extern contextItem menu_geometry_elementary_add_symmetry[]; -extern contextItem menu_geometry_elementary_translate[]; -extern contextItem menu_geometry_elementary_rotate[]; -extern contextItem menu_geometry_elementary_scale[]; -extern contextItem menu_geometry_elementary_symmetry[]; -extern contextItem menu_geometry_elementary_extrude[]; -extern contextItem menu_geometry_elementary_extrude_translate[]; -extern contextItem menu_geometry_elementary_extrude_rotate[]; -extern contextItem menu_geometry_elementary_delete[]; -extern contextItem menu_geometry_elementary_split[]; -extern contextItem menu_geometry_physical[]; -extern contextItem menu_geometry_physical_add[]; -extern contextItem menu_mesh[]; -extern contextItem menu_mesh_edit[]; -extern contextItem menu_mesh_delete[]; -extern contextItem menu_mesh_define[]; -extern contextItem menu_mesh_define_transfinite[]; -extern contextItem menu_mesh_define_compound[]; -extern contextItem menu_mesh_degree[]; -extern contextItem menu_solver[]; -extern contextItem menu_post[]; - -class menuWindow{ - private: - int _MH; - public: - Fl_Window *win; -#if defined(__APPLE__) - Fl_Sys_Menu_Bar *sysbar; -#endif - Fl_Menu_Bar *bar; - Fl_Choice *module; - Fl_Button *navig[2]; - Fl_Scroll *scroll; - std::vector<Fl_Button*> push; - std::vector<Fl_Light_Button*> toggle; - std::vector<Fl_Button*> toggle2; - std::vector<popupButton*> popup; - std::vector<popupButton*> popup2; - std::vector<char*> label, label2; - public: - menuWindow(); - void setContext(contextItem *menu_asked, int flag); - void fillRecentHistoryMenu(); -}; - -void file_quit_cb(Fl_Widget *w, void *data); -void file_watch_cb(Fl_Widget *w, void *data); -void mod_geometry_cb(Fl_Widget *w, void *data); -void mod_mesh_cb(Fl_Widget *w, void *data); -void mod_solver_cb(Fl_Widget *w, void *data); -void mod_post_cb(Fl_Widget *w, void *data); -void mod_back_cb(Fl_Widget *w, void *data); -void mod_forward_cb(Fl_Widget *w, void *data); -void geometry_reload_cb(Fl_Widget *w, void *data); -void mesh_1d_cb(Fl_Widget *w, void *data); -void mesh_2d_cb(Fl_Widget *w, void *data); -void mesh_3d_cb(Fl_Widget *w, void *data); -void help_about_cb(Fl_Widget *w, void *data); - -#endif diff --git a/Fltk/onelabWindow.cpp b/Fltk/onelabGroup.cpp similarity index 90% rename from Fltk/onelabWindow.cpp rename to Fltk/onelabGroup.cpp index af83909db00f639c4522091bfebc7e0e00b9994c..0d82e89a9927e5036ec75b2688ad4a6e342bd69a 100644 --- a/Fltk/onelabWindow.cpp +++ b/Fltk/onelabGroup.cpp @@ -12,28 +12,21 @@ typedef unsigned long intptr_t; #endif #include "GmshMessage.h" - -#if defined(HAVE_ONELAB) #include "onelab.h" -#endif - -#if defined(HAVE_ONELAB_METAMODEL) -#include "metamodel.h" -#endif - -#if defined(HAVE_ONELAB) && (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3) - #include <FL/Fl_Check_Button.H> #include <FL/Fl_Box.H> +#include <FL/Fl_Choice.H> +#include <FL/Fl_Light_Button.H> #include <FL/Fl_Input_Choice.H> #include <FL/Fl_Output.H> #include <FL/fl_ask.H> #include "inputRange.h" #include "inputRegion.h" +#include "viewButton.h" #include "paletteWindow.h" -#include "menuWindow.h" +#include "graphicWindow.h" #include "fileDialogs.h" -#include "onelabWindow.h" +#include "onelabGroup.h" #include "FlGui.h" #include "Context.h" #include "GModel.h" @@ -47,9 +40,13 @@ typedef unsigned long intptr_t; #include "drawContext.h" #include "PView.h" +#if defined(HAVE_ONELAB_METAMODEL) +#include "metamodel.h" +#endif + // This file contains the Gmsh/FLTK specific parts of the OneLab -// interface. You'll need to reimplement this if you plan to build -// a different OneLab server. +// interface. You'll need to reimplement this if you plan to build a different +// OneLab server. class onelabGmshServer : public GmshServer{ private: @@ -148,7 +145,7 @@ bool onelab::localNetworkClient::run() return false; } - Msg::StatusBar(2, true, "Running '%s'...", _name.c_str()); + Msg::StatusBar(true, "Running '%s'...", _name.c_str()); while(1) { @@ -286,7 +283,7 @@ bool onelab::localNetworkClient::run() } break; case GmshSocket::GMSH_PROGRESS: - Msg::StatusBar(2, false, "%s %s", _name.c_str(), message.c_str()); + Msg::StatusBar(false, "%s %s", _name.c_str(), message.c_str()); break; case GmshSocket::GMSH_INFO: Msg::Direct("%-8.8s: %s", _name.c_str(), message.c_str()); @@ -303,8 +300,10 @@ bool onelab::localNetworkClient::run() MergePostProcessingFile(message, CTX::instance()->solver.autoShowLastStep, CTX::instance()->solver.autoHideNewViews, true); drawContext::global()->draw(); - if(n != PView::list.size()) - FlGui::instance()->menu->setContext(menu_post, 0); + if(n != PView::list.size()){ + FlGui::instance()->rebuildTree(); + FlGui::instance()->openModule("Post-processing"); + } } break; case GmshSocket::GMSH_PARSE_STRING: @@ -333,7 +332,7 @@ bool onelab::localNetworkClient::run() server->Shutdown(); delete server; - Msg::StatusBar(2, true, "Done running '%s'", _name.c_str()); + Msg::StatusBar(true, "Done running '%s'", _name.c_str()); if(command.empty()){ Msg::Info("Client disconnected: starting new connection"); @@ -363,7 +362,7 @@ static void initializeLoops() onelabUtils::initializeLoop("3"); if(onelab::server::instance()->getChanged()) - FlGui::instance()->onelab->rebuildTree(); + FlGui::instance()->rebuildTree(); } static bool incrementLoops() @@ -374,7 +373,7 @@ static bool incrementLoops() else if(onelabUtils::incrementLoop("1")) ret = true; if(onelab::server::instance()->getChanged()) - FlGui::instance()->onelab->rebuildTree(); + FlGui::instance()->rebuildTree(); return ret; } @@ -404,9 +403,9 @@ static std::string timeStamp() static void saveDb(const std::string &fileName) { - Msg::StatusBar(2, true, "Saving database '%s'...", fileName.c_str()); + Msg::StatusBar(true, "Saving database '%s'...", fileName.c_str()); if(onelab::server::instance()->toFile(fileName)) - Msg::StatusBar(2, true, "Done saving database '%s'", fileName.c_str()); + Msg::StatusBar(true, "Done saving database '%s'", fileName.c_str()); else Msg::Error("Could not save database '%s'", fileName.c_str()); } @@ -449,14 +448,14 @@ static void archiveOutputFiles(const std::string &fileName) saveDb(split[0] + "archive/" + split[1] + stamp + split[2]); } - FlGui::instance()->onelab->rebuildTree(); + FlGui::instance()->rebuildTree(); } static void loadDb(const std::string &name) { - Msg::StatusBar(2, true, "Loading database '%s'...", name.c_str()); + Msg::StatusBar(true, "Loading database '%s'...", name.c_str()); if(onelab::server::instance()->fromFile(name)) - Msg::StatusBar(2, true, "Done loading database '%s'", name.c_str()); + Msg::StatusBar(true, "Done loading database '%s'", name.c_str()); else Msg::Error("Could not load database '%s'", name.c_str()); } @@ -468,9 +467,7 @@ void onelab_cb(Fl_Widget *w, void *data) if(action == "refresh"){ updateGraphs(); - FlGui::instance()->onelab->rebuildTree(); - if(!FlGui::instance()->onelab->shown()) - FlGui::instance()->onelab->show(); + FlGui::instance()->rebuildTree(); return; } @@ -591,7 +588,7 @@ void onelab_cb(Fl_Widget *w, void *data) if(action != "initialize"){ updateGraphs(); - FlGui::instance()->onelab->rebuildTree(); + FlGui::instance()->rebuildTree(); } } while(action == "compute" && !FlGui::instance()->onelab->stop() && @@ -691,6 +688,7 @@ static void onelab_tree_cb(Fl_Widget *w, void *data) std::vector<onelab::string> strings; std::vector<onelab::region> regions; std::vector<onelab::function> functions; + switch(tree->callback_reason()){ case FL_TREE_REASON_SELECTED: break; case FL_TREE_REASON_DESELECTED: break; @@ -711,33 +709,31 @@ static void onelab_tree_cb(Fl_Widget *w, void *data) } } -onelabWindow::onelabWindow(int deltaFontSize) - : _deltaFontSize(deltaFontSize), _stop(false) +onelabGroup::onelabGroup(int x, int y, int w, int h, const char *l) + : Fl_Group(x,y,w,h,l), _stop(false) { - FL_NORMAL_SIZE -= _deltaFontSize; - - int width = CTX::instance()->solverSize[0]; - int height = CTX::instance()->solverSize[1]; - - _win = new paletteWindow - (width, height, CTX::instance()->nonModalWindows ? true : false, "OneLab"); - _win->box(GMSH_WINDOW_BOX); - - _tree = new Fl_Tree(WB, WB, width - 2 * WB, height - 3 * WB - BH); + _tree = new Fl_Tree(x, y, w, h - BH - 2 * WB); _tree->callback(onelab_tree_cb); _tree->connectorstyle(FL_TREE_CONNECTOR_SOLID); _tree->showroot(0); + _tree->box(FL_FLAT_BOX); + _tree->scrollbar_size(std::max(10, FL_NORMAL_SIZE - 2)); _itemWidth = (int)(0.4 * _tree->w()); - _butt[0] = new Fl_Button(width - 2*WB - 2*BB, height - WB - BH, BB, BH, "Check"); + box(FL_FLAT_BOX); + color(_tree->color()); + + int BB2 = BB / 2 + 4; + + _butt[0] = new Fl_Button(x + w - 3 * WB - 3 * BB2, y + h - WB - BH, BB2, BH, "Check"); _butt[0]->callback(onelab_cb, (void*)"check"); - _butt[1] = new Fl_Button(width - WB - BB, height - WB - BH, BB, BH, "Compute"); + + _butt[1] = new Fl_Button(x + w - 2 * WB - 2 * BB2, y + h - WB - BH, BB2, BH, "Run"); _butt[1]->callback(onelab_cb, (void*)"compute"); - int BB2 = BB / 2 + 4; _gear = new Fl_Menu_Button - (_butt[0]->x() - WB - BB2, _butt[0]->y(), BB2, BH, "@-1gmsh_gear"); + (x + w - WB - BB2, y + h - WB - BH, BB2, BH, "@-1gmsh_gear"); _gear->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); _gear->add("Reset database", 0, onelab_cb, (void*)"reset"); _gear->add("Save database...", 0, onelab_cb, (void*)"save"); @@ -762,19 +758,12 @@ onelabWindow::onelabWindow(int deltaFontSize) _gearOptionsEnd = _gear->menu()->size(); - Fl_Box *resbox = new Fl_Box(WB, WB, - width - 2 * BB - BB2 - 4 * WB, - height - 3 * WB - BH); - _win->resizable(resbox); - _win->size_range(2 * BB + BB2 + 4 * WB + 1, 2 * BH + 3 * WB); - - _win->position - (CTX::instance()->solverPosition[0], CTX::instance()->solverPosition[1]); - _win->end(); + end(); - setButtonVisibility(); + Fl_Box *resbox = new Fl_Box(x + WB, y + WB, WB, WB); + resizable(resbox); - FL_NORMAL_SIZE += _deltaFontSize; + rebuildSolverList(); } static bool getFlColor(const std::string &str, Fl_Color &c) @@ -810,7 +799,7 @@ static void autoCheck(const T &pold, const T &pnew, bool force=false) } template<class T> -void onelabWindow::_addParameter(T &p) +void onelabGroup::_addParameter(T &p) { bool highlight = false; Fl_Color c; @@ -825,6 +814,45 @@ void onelabWindow::_addParameter(T &p) _tree->end(); } +void onelabGroup::_addMenu(const std::string &path, Fl_Callback *callback, void *data) +{ + Fl_Tree_Item *n = _tree->add(path.c_str()); + n->labelsize(FL_NORMAL_SIZE + 5); + _tree->begin(); + Fl_Button *but = new Fl_Button(1, 1, (3 * _itemWidth) / 2, 1); + but->align(FL_ALIGN_INSIDE | FL_ALIGN_CLIP); + but->callback(callback, data); + _treeWidgets.push_back(but); + std::string label = path; + std::string::size_type last = path.find_last_of('/'); + if(last != std::string::npos) label = path.substr(last + 1); + but->copy_label(label.c_str()); + n->widget(but); + _tree->end(); +} + +void onelabGroup::_addViewMenu(int num) +{ + std::ostringstream path; + path << "0Gmsh modules/Post-processing/View" << num; + Fl_Tree_Item *n = _tree->add(path.str().c_str()); + n->labelsize(FL_NORMAL_SIZE + 5); + _tree->begin(); + viewButton *but = new viewButton(1, 1, (7 * _itemWidth) / 4, 1, num); + _treeWidgets.push_back(but); + n->widget(but); + _tree->end(); +} + +viewButton *onelabGroup::getViewButton(int num) +{ + char tmp[256]; + sprintf(tmp, "0Gmsh modules/Post-processing/View%d", num); + Fl_Tree_Item *n = _tree->find_item(tmp); + if(n) return (viewButton*)n->widget(); + return 0; +} + static void onelab_number_check_button_cb(Fl_Widget *w, void *data) { if(!data) return; @@ -881,8 +909,8 @@ static void onelab_number_input_range_cb(Fl_Widget *w, void *data) } } -Fl_Widget *onelabWindow::_addParameterWidget(onelab::number &p, Fl_Tree_Item *n, - bool highlight, Fl_Color c) +Fl_Widget *onelabGroup::_addParameterWidget(onelab::number &p, Fl_Tree_Item *n, + bool highlight, Fl_Color c) { // non-editable value if(p.getReadOnly()){ @@ -1002,12 +1030,12 @@ static void onelab_input_choice_file_merge_cb(Fl_Widget *w, void *data) drawContext::global()->draw(); } -Fl_Widget *onelabWindow::_addParameterWidget(onelab::string &p, Fl_Tree_Item *n, - bool highlight, Fl_Color c) +Fl_Widget *onelabGroup::_addParameterWidget(onelab::string &p, Fl_Tree_Item *n, + bool highlight, Fl_Color c) { // macro button if(p.getKind() == "macro"){ - Fl_Button *but = new Fl_Button(1, 1, _itemWidth, 1); + Fl_Button *but = new Fl_Button(1, 1, (3 * _itemWidth) / 2, 1); but->align(FL_ALIGN_INSIDE | FL_ALIGN_CLIP); but->callback(onelab_string_button_cb, (void*)n); if(highlight) but->color(c); @@ -1070,8 +1098,8 @@ static void onelab_region_input_cb(Fl_Widget *w, void *data) } } -Fl_Widget *onelabWindow::_addParameterWidget(onelab::region &p, Fl_Tree_Item *n, - bool highlight, Fl_Color c) +Fl_Widget *onelabGroup::_addParameterWidget(onelab::region &p, Fl_Tree_Item *n, + bool highlight, Fl_Color c) { // non-editable value if(p.getReadOnly()){ @@ -1090,8 +1118,8 @@ Fl_Widget *onelabWindow::_addParameterWidget(onelab::region &p, Fl_Tree_Item *n, return but; } -Fl_Widget *onelabWindow::_addParameterWidget(onelab::function &p, Fl_Tree_Item *n, - bool highlight, Fl_Color c) +Fl_Widget *onelabGroup::_addParameterWidget(onelab::function &p, Fl_Tree_Item *n, + bool highlight, Fl_Color c) { // non-editable value if(1 || p.getReadOnly()){ @@ -1103,13 +1131,18 @@ Fl_Widget *onelabWindow::_addParameterWidget(onelab::function &p, Fl_Tree_Item * } } -void onelabWindow::rebuildTree() +static void onelab_subtree_cb(Fl_Widget *w, void *data) { - FL_NORMAL_SIZE -= _deltaFontSize; + Fl_Tree_Item *n = (Fl_Tree_Item*)data; + n->open_toggle(); + FlGui::instance()->onelab->redrawTree(); +} +void onelabGroup::rebuildTree() +{ _itemWidth = (int)(0.4 * _tree->w()); - std::set<std::string> closed; + std::set<std::string> closed = _getClosedGmshMenus(); _tree->clear(); _tree->sortorder(FL_TREE_SORT_ASCENDING); @@ -1122,6 +1155,8 @@ void onelabWindow::rebuildTree() free(_treeStrings[i]); _treeStrings.clear(); + _addGmshMenus(); + std::vector<onelab::number> numbers; onelab::server::instance()->get(numbers); for(unsigned int i = 0; i < numbers.size(); i++){ @@ -1161,8 +1196,11 @@ void onelabWindow::rebuildTree() for(Fl_Tree_Item *n = _tree->first(); n; n = n->next()){ if(n->has_children()){ _tree->begin(); - Fl_Box *but = new Fl_Box(1, 1, _itemWidth, 1); + Fl_Button *but = new Fl_Button(1, 1, _itemWidth, 1); + but->box(FL_NO_BOX); + but->clear_visible_focus(); but->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE); + but->callback(onelab_subtree_cb, (void*)n); _treeWidgets.push_back(but); onelab::string o(n->label()); but->copy_label(o.getShortName().c_str()); @@ -1177,11 +1215,18 @@ void onelabWindow::rebuildTree() _tree->redraw(); FlGui::check(); // necessary e.g. on windows to avoid "ghosting" +} - FL_NORMAL_SIZE += _deltaFontSize; +void onelabGroup::openTreeItem(const std::string &name) +{ + Fl_Tree_Item *n = _tree->find_item(name.c_str()); + if(n && n->has_children()){ + n->open(); + _tree->redraw(); + } } -void onelabWindow::checkForErrors(const std::string &client) +void onelabGroup::checkForErrors(const std::string &client) { if(Msg::GetErrorCount() > 0 && !CTX::instance()->expertMode){ Msg::ResetErrorCounter(); @@ -1194,24 +1239,22 @@ void onelabWindow::checkForErrors(const std::string &client) } } -void onelabWindow::setButtonVisibility() +void onelabGroup::setButtonVisibility() { - if(_butt[0]->visible() && CTX::instance()->solver.autoCheck){ + if(!CTX::instance()->solver.autoCheck) + _butt[0]->show(); + else _butt[0]->hide(); - _gear->position(_gear->x() + _butt[0]->w() + WB, _gear->y()); - _win->init_sizes(); - _win->redraw(); - } - if(!_butt[0]->visible() && !CTX::instance()->solver.autoCheck){ - _butt[0]->show(); - _gear->position(_gear->x() - _butt[0]->w() - WB, _gear->y()); - _win->init_sizes(); - _win->redraw(); - } + if(onelab::server::instance()->getNumClients() > 1) + _butt[1]->show(); + else + _butt[1]->hide(); + + redraw(); } -void onelabWindow::setButtonMode(const std::string &butt0, const std::string &butt1) +void onelabGroup::setButtonMode(const std::string &butt0, const std::string &butt1) { if(butt0 == "check"){ _butt[0]->activate(); @@ -1224,7 +1267,7 @@ void onelabWindow::setButtonMode(const std::string &butt0, const std::string &bu if(butt1 == "compute"){ _butt[1]->activate(); - _butt[1]->label("Compute"); + _butt[1]->label("Run"); _butt[1]->callback(onelab_cb, (void*)"compute"); for(int i = 0; i < _gear->menu()->size(); i++) ((Fl_Menu_Item*)_gear->menu())[i].activate(); @@ -1253,14 +1296,14 @@ void onelabWindow::setButtonMode(const std::string &butt0, const std::string &bu } } -bool onelabWindow::isBusy() +bool onelabGroup::isBusy() { std::string s(_butt[1]->label()); - if(s == "Compute") return false; + if(s == "Run") return false; return true; } -void onelabWindow::rebuildSolverList() +void onelabGroup::rebuildSolverList() { // update OneLab window title and gear menu _title = "OneLab"; @@ -1295,7 +1338,7 @@ void onelabWindow::rebuildSolverList() _title += " " + it->second->getName(); } _gear->add("Add new client...", 0, onelab_add_solver_cb); - _win->label(_title.c_str()); + //label(_title.c_str()); // update Gmsh solver menu std::vector<std::string> names, exes, hosts; @@ -1321,11 +1364,13 @@ void onelabWindow::rebuildSolverList() opt_solver_remote_login(i, GMSH_SET, ""); } } - FlGui::instance()->menu->setContext(menu_solver, 0); + + setButtonVisibility(); + rebuildTree(); } -void onelabWindow::addSolver(const std::string &name, const std::string &executable, - const std::string &remoteLogin, int index) +void onelabGroup::addSolver(const std::string &name, const std::string &executable, + const std::string &remoteLogin, int index) { if(onelab::server::instance()->findClient(name) != onelab::server::instance()->lastClient()) return; // solver already exists @@ -1356,7 +1401,7 @@ void onelabWindow::addSolver(const std::string &name, const std::string &executa onelab_cb(0, (void*)"initialize"); } -void onelabWindow::removeSolver(const std::string &name) +void onelabGroup::removeSolver(const std::string &name) { onelab::server::citer it = onelab::server::instance()->findClient(name); if(it != onelab::server::instance()->lastClient()){ @@ -1385,8 +1430,9 @@ void solver_cb(Fl_Widget *w, void *data) std::string host = opt_solver_remote_login(num, GMSH_GET, ""); FlGui::instance()->onelab->addSolver(name, exe, host, num); } - else + else{ FlGui::instance()->onelab->rebuildSolverList(); + } if(CTX::instance()->solver.autoSaveDatabase){ std::string db = SplitFileName(GModel::current()->getFileName())[0] + "onelab.db"; @@ -1398,7 +1444,7 @@ void solver_cb(Fl_Widget *w, void *data) else onelab_cb(0, (num >= 0) ? (void*)"check" : (void*)"refresh"); - CTX::instance()->launchOnelabAtStartup = -2; + CTX::instance()->launchSolverAtStartup = -1; } void flgui_wait_cb(double time) @@ -1440,34 +1486,3 @@ int metamodel_cb(const std::string &name, const std::string &action) return 0; #endif } - -#else - -#if defined(HAVE_ONELAB) - -bool onelab::localNetworkClient::run() -{ - Msg::Error("The solver interface requires OneLab and FLTK 1.3"); - return false; -} - -bool onelab::localNetworkClient::kill() -{ - Msg::Error("The solver interface requires OneLab and FLTK 1.3"); - return false; -} - -#endif - -void solver_cb(Fl_Widget *w, void *data) -{ - Msg::Error("The solver interface requires OneLab and FLTK 1.3"); -} - -int metamodel_cb(const std::string &name, const std::string &action) -{ - Msg::Error("Metamodels require OneLab and FLTK 1.3"); - return 0; -} - -#endif diff --git a/Fltk/onelabWindow.h b/Fltk/onelabGroup.h similarity index 82% rename from Fltk/onelabWindow.h rename to Fltk/onelabGroup.h index 57ecc25e9a985d219087b5aa7f22be3a9d307b60..ee7c35fe5bdaec9f7f7632763bd1383c55c13bd7 100644 --- a/Fltk/onelabWindow.h +++ b/Fltk/onelabGroup.h @@ -6,21 +6,18 @@ #ifndef _ONELAB_WINDOW_H_ #define _ONELAB_WINDOW_H_ -#include "GmshConfig.h" -#include <FL/Fl.H> - -#if defined(HAVE_ONELAB) && (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3) #include <vector> -#include <FL/Fl_Window.H> +#include <FL/Fl.H> #include <FL/Fl_Tree.H> #include <FL/Fl_Button.H> #include <FL/Fl_Menu_Button.H> #include <FL/Fl_Input.H> #include "onelab.h" -class onelabWindow{ +class viewButton; + +class onelabGroup : public Fl_Group{ private: - Fl_Window *_win; Fl_Tree *_tree; Fl_Button *_butt[2]; Fl_Menu_Button *_gear; @@ -28,7 +25,6 @@ class onelabWindow{ std::vector<Fl_Widget*> _treeWidgets; std::vector<char*> _treeStrings; std::string _title; - int _deltaFontSize; bool _stop; int _itemWidth; template <class T> void _addParameter(T &p); @@ -40,25 +36,26 @@ class onelabWindow{ bool highlight, Fl_Color c); Fl_Widget *_addParameterWidget(onelab::function &p, Fl_Tree_Item *n, bool highlight, Fl_Color c); + void _addMenu(const std::string &path, Fl_Callback *callback, void *data); + void _addViewMenu(int num); + std::set<std::string> _getClosedGmshMenus(); + void _addGmshMenus(); public: - onelabWindow(int deltaFontSize=0); - int x(){ return _win->x(); } - int y(){ return _win->y(); } - int w(){ return _win->w(); } - int h(){ return _win->h(); } + onelabGroup(int x, int y, int w, int h, const char *l=0); void rebuildSolverList(); void rebuildTree(); + void redrawTree(){ _tree->redraw(); } + void openTreeItem(const std::string &name); void setButtonVisibility(); void setButtonMode(const std::string &butt0, const std::string &butt1); bool isBusy(); - void show(){ _win->show(); } - int shown(){ return _win->shown(); } std::string getPath(Fl_Tree_Item *item) { char path[1024]; _tree->item_pathname(path, 1024, item); return std::string(path); } + viewButton *getViewButton(int num); void addSolver(const std::string &name, const std::string &exe, const std::string &hostName, int index); void removeSolver(const std::string &name); @@ -68,9 +65,6 @@ class onelabWindow{ }; void onelab_cb(Fl_Widget *w, void *data); - -#endif - void solver_cb(Fl_Widget *w, void *data); int metamodel_cb(const std::string &name, const std::string &action=""); diff --git a/Fltk/openglWindow.cpp b/Fltk/openglWindow.cpp index a767894aba8c18b95d09446dbffed42529a1ddd2..905a9e8f7e188f1ed1ee8bc2ea38195fea0e58cc 100644 --- a/Fltk/openglWindow.cpp +++ b/Fltk/openglWindow.cpp @@ -39,8 +39,8 @@ static void lassoZoom(drawContext *ctx, mousePosition &click1, mousePosition &cl FlGui::instance()->manip->update(); } -openglWindow::openglWindow(int x, int y, int w, int h, const char *l) - : Fl_Gl_Window(x, y, w, h, l), _lock(false), +openglWindow::openglWindow(int x, int y, int w, int h) + : Fl_Gl_Window(x, y, w, h, "gl"), _lock(false), _selection(ENT_NONE), _trySelection(0) { _ctx = new drawContext(); @@ -85,40 +85,46 @@ void openglWindow::_drawScreenMessage() void openglWindow::_drawBorder() { - // draw thin border if the parent group has more than 2 children (it - // has at least 2: the message console and one opengl window) - if(parent()->children() > 2){ - unsigned char r, g, b; - Fl::get_color(color(), r, g, b); - /* would need to redraw all gl's when _lastHandled is changed - if(_lastHandled == this) - Fl::get_color(FL_SELECTION_COLOR, r, g, b); - else - Fl::get_color(FL_BACKGROUND_COLOR, r, g, b); - */ - glColor3ub(r, g, b); - glLineWidth(1.0F); - glBegin(GL_LINE_LOOP); - glVertex2d(_ctx->viewport[0], _ctx->viewport[1]); - glVertex2d(_ctx->viewport[2], _ctx->viewport[1]); - glVertex2d(_ctx->viewport[2], _ctx->viewport[3]); - glVertex2d(_ctx->viewport[0], _ctx->viewport[3]); - glEnd(); + // draw thin border if the parent group has more than 2 opengl windows + int numgl = 0; + for(int i = 0; i < parent()->children(); i++){ + if(parent()->child(i)->label() && + !strcmp(parent()->child(i)->label(), label())) + numgl++; } + if(numgl < 2) return; + + unsigned char r, g, b; + Fl::get_color(color(), r, g, b); + /* would need to redraw all gl's when _lastHandled is changed + if(_lastHandled == this) + Fl::get_color(FL_SELECTION_COLOR, r, g, b); + else + Fl::get_color(FL_BACKGROUND_COLOR, r, g, b); + */ + glColor3ub(r, g, b); + glLineWidth(1.0F); + glBegin(GL_LINE_LOOP); + glVertex2d(_ctx->viewport[0], _ctx->viewport[1]); + glVertex2d(_ctx->viewport[2], _ctx->viewport[1]); + glVertex2d(_ctx->viewport[2], _ctx->viewport[3]); + glVertex2d(_ctx->viewport[0], _ctx->viewport[3]); + glEnd(); } void openglWindow::draw() { - // some drawing routines can create data (STL triangulations, etc.): - // make sure that we don't fire draw() while we are already drawing, - // e.g. due to an impromptu Fl::check(). The same lock is also used - // in _select to guarantee that we don't mix GL_RENDER and GL_SELECT - // rendering passes. + // some drawing routines can create data (STL triangulations, etc.): make sure + // that we don't fire draw() while we are already drawing, e.g. due to an + // impromptu Fl::check(). The same lock is also used in _select to guarantee + // that we don't mix GL_RENDER and GL_SELECT rendering passes. if(_lock) return; _lock = true; Msg::Debug("openglWindow::draw()"); + if(!context_valid()) _ctx->invalidateQuadricsAndDisplayLists(); + _ctx->viewport[0] = 0; _ctx->viewport[1] = 0; _ctx->viewport[2] = w(); @@ -127,8 +133,8 @@ void openglWindow::draw() _ctx->viewport[2], _ctx->viewport[3]); if(lassoMode) { - // draw the zoom or selection lasso on top of the current scene - // (without using overlays!) + // draw the zoom or selection lasso on top of the current scene (without + // using overlays!) glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho((double)_ctx->viewport[0], (double)_ctx->viewport[2], @@ -224,7 +230,6 @@ void openglWindow::draw() _ctx->draw2d(); _drawScreenMessage(); _drawBorder(); - // glPushMatrix(); } else if(CTX::instance()->stereo){ Camera *cam = &(_ctx->camera); @@ -588,7 +593,7 @@ int openglWindow::handle(int event) if(CTX::instance()->tooltips) drawTooltip(text); else - Msg::StatusBar(2, false, text.c_str()); + Msg::StatusBar(false, text.c_str()); } } _prev.set(_ctx, Fl::event_x(), Fl::event_y()); diff --git a/Fltk/openglWindow.h b/Fltk/openglWindow.h index 9344a1d2c6f905eb587d2f9be39579f93c10c3df..6d18f53b4d9470be94e6916a70ebc472aad1560d 100644 --- a/Fltk/openglWindow.h +++ b/Fltk/openglWindow.h @@ -41,7 +41,7 @@ class openglWindow : public Fl_Gl_Window { bool addPointMode, lassoMode, selectionMode; int endSelection, undoSelection, invertSelection, quitSelection; std::string screenMessage[2]; - openglWindow(int x, int y, int w, int h, const char *l=0); + openglWindow(int x, int y, int w, int h); ~openglWindow(); drawContext *getDrawContext(){ return _ctx; } char selectEntity(int type, diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp index ae493642518ebdc19cc3fbe28d157c1a57c6f1fb..34155a30238bd6d21132acbe56bbb176b7ab2d8a 100644 --- a/Fltk/optionWindow.cpp +++ b/Fltk/optionWindow.cpp @@ -17,8 +17,9 @@ typedef unsigned long intptr_t; #include "GmshMessage.h" #include "FlGui.h" #include "optionWindow.h" +#include "graphicWindow.h" +#include "openglWindow.h" #include "paletteWindow.h" -#include "menuWindow.h" #include "extraDialogs.h" #include "drawContext.h" #include "Options.h" @@ -29,8 +30,6 @@ typedef unsigned long intptr_t; #include "PViewOptions.h" #include "OS.h" #include "Context.h" -#include "graphicWindow.h" -#include "openglWindow.h" #if defined(HAVE_ONELAB) #include "onelab.h" @@ -174,8 +173,7 @@ static void options_restore_defaults_cb(Fl_Widget *w, void *data) UnlinkFile(CTX::instance()->homeDir + CTX::instance()->optionsFileName); ReInitOptions(0); InitOptionsGUI(0); - if(FlGui::instance()->menu->module->value() == 3) // hack to refresh the buttons - FlGui::instance()->menu->setContext(menu_post, 0); + FlGui::instance()->rebuildTree(); drawContext::global()->draw(); } @@ -193,7 +191,7 @@ static void general_options_color_scheme_cb(Fl_Widget *w, void *data) static void general_options_rotation_center_select_cb(Fl_Widget *w, void *data) { - Msg::StatusBar(3, false, "Select entity or element\n[Press 'q' to abort]"); + Msg::StatusGl("Select entity or element\n[Press 'q' to abort]"); CTX::instance()->pickElements = 1; CTX::instance()->mesh.changed = ENT_ALL; @@ -221,7 +219,7 @@ static void general_options_rotation_center_select_cb(Fl_Widget *w, void *data) CTX::instance()->mesh.changed = ENT_ALL; GModel::current()->setSelection(0); drawContext::global()->draw(); - Msg::StatusBar(3, false, ""); + Msg::StatusGl(""); } static void general_options_ok_cb(Fl_Widget *w, void *data) diff --git a/Fltk/popupButton.h b/Fltk/popupButton.h deleted file mode 100644 index b9966dcea36ed7bfca1be9b9d91c818ed677a6dd..0000000000000000000000000000000000000000 --- a/Fltk/popupButton.h +++ /dev/null @@ -1,66 +0,0 @@ -// Gmsh - Copyright (C) 1997-2012 C. Geuzaine, J.-F. Remacle -// -// See the LICENSE.txt file for license information. Please report all -// bugs and problems to <gmsh@geuz.org>. - -#ifndef _POPUP_BUTTON_H -#define _POPUP_BUTTON_H - -#include <FL/Fl.H> -#include <FL/Fl_Menu_Button.H> - -// This is needed for FLTK < 1.1.8 (popup() in 1.1.7 calls redraw() -// after picked(), which can cause a crash if the button was deleted -// by the callback) -class popupButton : public Fl_Menu_Button { - public: - popupButton(int x, int y, int w, int h, char *label=0) - : Fl_Menu_Button(x, y, w, h, label) {} - void draw(){ Fl_Menu_Button::draw(); } - int handle(int e) - { - if (!menu() || !menu()->text) return 0; - switch (e) { - case FL_ENTER: - case FL_LEAVE: - return (box() && !type()) ? 1 : 0; - case FL_PUSH: - if (!box()) { - if (Fl::event_button() != 3) return 0; - } else if (type()) { - if (!(type() & (1 << (Fl::event_button()-1)))) return 0; - } - if (Fl::visible_focus()) Fl::focus(this); - popup(); - return 1; - case FL_KEYBOARD: - if (!box()) return 0; - if (Fl::event_key() == ' ' && - !(Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT | FL_META))) { - popup(); - return 1; - } else return 0; - case FL_SHORTCUT: - if (Fl_Widget::test_shortcut()) {popup(); return 1;} - return test_shortcut() != 0; - case FL_FOCUS: - case FL_UNFOCUS: - if (box() && Fl::visible_focus()) { - redraw(); - return 1; - } - default: - return 0; - } - } - const Fl_Menu_Item* popup() - { - const Fl_Menu_Item* m; - redraw(); - m = menu()->popup(Fl::event_x(), Fl::event_y(), label(), mvalue(), this); - picked(m); - return m; - } -}; - -#endif diff --git a/Fltk/projectionEditor.cpp b/Fltk/projectionEditor.cpp index e8d7ba60034d47d4a46c843bf885e9b0923259d0..80c2290a680ec6367ffb2a5865c3bb39cd3d4501 100644 --- a/Fltk/projectionEditor.cpp +++ b/Fltk/projectionEditor.cpp @@ -63,10 +63,10 @@ static fourierProjectionFace *createProjectionFaceFromName(const char *name) } static void project_point(FM::ProjectionSurface *ps, double x, double y, double z, - std::vector<double> &u, std::vector<double> &v, + std::vector<double> &u, std::vector<double> &v, std::vector<double> &dist, std::vector<std::complex<double> > &f) -{ +{ double uu, vv, p[3], n[3]; ps->OrthoProjectionOnSurface(x, y, z, uu, vv); if(uu >= 0. && uu <= 1. && vv >= 0. && vv <= 1.){ @@ -95,7 +95,7 @@ static void getTangents(const SVector3 n, SVector3 &t1, SVector3 &t2, const doub b.normalize(); double x = n[0], y = n[1], z = n[2]; double c = cos(angle * M_PI / 180.), s = sin(angle * M_PI / 180.); - double rot[3][3] = + double rot[3][3] = {{x * x * (1-c) + c , x * y * (1-c) - z * s, x * z * (1-c) + y * s}, {y * x * (1-c) + z * s, y * y * (1-c) + c , y * z * (1-c) - x * s}, {x * z * (1-c) - y * s, y * z * (1-c) + x * s, z * z * (1-c) + c }}; @@ -173,7 +173,7 @@ static void browse_cb(Fl_Widget *w, void *data) projections[i]->face->setVisibility(false); projections[i]->group->hide(); } - + projection *p = e->getCurrentProjection(); if(p){ p->face->setVisibility(true); @@ -282,18 +282,18 @@ static void select_cb(Fl_Widget *w, void *data) drawContext::global()->draw(); if(ele.size() || ent.size()) - Msg::StatusBar(3, false, "Select %s\n[Press 'e' to end selection, 'u' to undo" - "last selection or 'q' to abort]", str); + Msg::StatusGl("Select %s\n[Press 'e' to end selection, 'u' to undo" + "last selection or 'q' to abort]", str); else - Msg::StatusBar(3, false, "Select %s\n" - "[Press 'e' to end selection or 'q' to abort]", str); + Msg::StatusGl("Select %s\n" + "[Press 'e' to end selection or 'q' to abort]", str); char ib = FlGui::instance()->selectEntity(what); if(ib == 'l') { if(CTX::instance()->pickElements){ for(unsigned int i = 0; i < FlGui::instance()->selectedElements.size(); i++){ if(FlGui::instance()->selectedElements[i]->getVisibility() != 2){ - FlGui::instance()->selectedElements[i]->setVisibility(2); + FlGui::instance()->selectedElements[i]->setVisibility(2); ele.push_back(FlGui::instance()->selectedElements[i]); } } @@ -353,8 +353,8 @@ static void select_cb(Fl_Widget *w, void *data) CTX::instance()->mesh.changed = ENT_ALL; CTX::instance()->pickElements = 0; - drawContext::global()->draw(); - Msg::StatusBar(3, false, ""); + drawContext::global()->draw(); + Msg::StatusGl(""); } static void filter_cb(Fl_Widget *w, void *data) @@ -428,7 +428,7 @@ static void save_selection_cb(Fl_Widget *w, void *data) for(unsigned int i = 0; i < ent.size(); i++){ GVertex *gv = dynamic_cast<GVertex*>(ent[i]); if(gv && gv->getSelection()) - fprintf(fp, "Point(%d) = {%.16g,%.16g,%.16g,1};\n", gv->tag(), + fprintf(fp, "Point(%d) = {%.16g,%.16g,%.16g,1};\n", gv->tag(), gv->x(), gv->y(), gv->z()); } std::vector<MElement*> &ele(e->getElements()); @@ -561,8 +561,8 @@ static void compute_cb(Fl_Widget *w, void *data) else { // create the Fourier faces (with boundaries) if(ps->IsUPeriodic()) { - FM::Patch* patchL = - new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes, + FM::Patch* patchL = + new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes, uM, vM, h0, h1, h2, h3); patchL->SetMinU(-0.35); patchL->SetMaxU(0.35); @@ -570,7 +570,7 @@ static void compute_cb(Fl_Widget *w, void *data) AddPatch(patchL); m->getFMInternals()->makeGFace(patchL,m); //makeGFace(patchL); - FM::Patch* patchR = + FM::Patch* patchR = new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes, uM, vM, h0, h1, h2, h3); patchR->SetMinU(0.15); @@ -581,8 +581,8 @@ static void compute_cb(Fl_Widget *w, void *data) //makeGFace(patchR); } else if (ps->IsVPeriodic()) { - FM::Patch* patchL = - new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes, + FM::Patch* patchL = + new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes, uM, vM, h0, h1, h2, h3); patchL->SetMinV(-0.35); patchL->SetMaxV(0.35); @@ -590,7 +590,7 @@ static void compute_cb(Fl_Widget *w, void *data) AddPatch(patchL); m->getFMInternals()->makeGFace(patchL,m); //makeGFace(patchL); - FM::Patch* patchR = + FM::Patch* patchR = new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes, uM, vM, h0, h1, h2, h3); patchR->SetMinV(0.15); @@ -601,8 +601,8 @@ static void compute_cb(Fl_Widget *w, void *data) //makeGFace(patchR); } else { - FM::Patch* patch = - new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes, + FM::Patch* patch = + new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes, uM, vM, h0, h1, h2, h3); m->getFMInternals()->current()->GetGroup(0)->GetBlendGroup()-> AddPatch(patch); @@ -665,7 +665,7 @@ static void action_cb(Fl_Widget *w, void *data) if(what == "delete_last" || what == "save_last"){ int id = -1; for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++) - if((*it)->getNativeType() == GEntity::FourierModel) + if((*it)->getNativeType() == GEntity::FourierModel) id = std::max(id, (*it)->tag()); if(id > 0) faces.push_back(m->getFaceByTag(id)); } @@ -675,16 +675,16 @@ static void action_cb(Fl_Widget *w, void *data) faces.push_back(*it); } else if(what == "delete_select" || what == "save_select"){ - Msg::StatusBar(3, false, "Select Surface\n[Press 'e' to end selection 'q' to abort]"); + Msg::StatusGl("Select Surface\n[Press 'e' to end selection 'q' to abort]"); char ib = FlGui::instance()->selectEntity(ENT_SURFACE); - if(ib == 'l') faces.insert(faces.end(), - FlGui::instance()->selectedFaces.begin(), + if(ib == 'l') faces.insert(faces.end(), + FlGui::instance()->selectedFaces.begin(), FlGui::instance()->selectedFaces.end()); - Msg::StatusBar(3, false, ""); + Msg::StatusGl(""); } if(what[0] == 'd'){ - for(unsigned int i = 0; i < faces.size(); i++) + for(unsigned int i = 0; i < faces.size(); i++) delete_fourier(faces[i]); } else{ @@ -702,7 +702,7 @@ static void action_cb(Fl_Widget *w, void *data) fclose(fp); } } - + drawContext::global()->draw(); } @@ -713,10 +713,10 @@ uvPlot::uvPlot(int x, int y, int w, int h, const char *l) ColorTable_Recompute(&_colorTable); } -void uvPlot::set(std::vector<double> &u, std::vector<double> &v, +void uvPlot::set(std::vector<double> &u, std::vector<double> &v, std::vector<double> &dist, std::vector<std::complex<double> > &f) -{ - _u = u; +{ + _u = u; _v = v; _dist = dist; _f = f; @@ -787,17 +787,17 @@ void uvPlot::draw() fl_draw(max, pw - (int)fl_width(max) - 5, h() - 5); } -projection::projection(fourierProjectionFace *f, int x, int y, int w, int h, - int bb, int bh, projectionEditor *e) +projection::projection(fourierProjectionFace *f, int x, int y, int w, int h, + int bb, int bh, projectionEditor *e) : face(f) { group = new Fl_Scroll(x, y, w, h); SBoundingBox3d bounds = GModel::current()->bounds(); FM::ProjectionSurface *ps = (FM::ProjectionSurface*)f->getNativePtr(); - + Fl_Toggle_Button *b = new Fl_Toggle_Button(x, y, bb, bh, "Set position"); b->callback(set_position_cb, e); - + { // origin is stored in parameters[0,1,2] SPoint3 pc = bounds.center(); for(int i = 0; i < 3; i++){ @@ -812,9 +812,9 @@ projection::projection(fourierProjectionFace *f, int x, int y, int w, int h, ps->SetOrigin(pc[0], pc[1], pc[2]); Fl_Repeat_Button *bm[3], *bp[3]; for(int i = 0; i < 3; i++){ - new Fl_Box(x + w - bb / 3 - bb / 6, y + (1 + i) * bh, bb / 8, bh, + new Fl_Box(x + w - bb / 3 - bb / 6, y + (1 + i) * bh, bb / 8, bh, (i == 0) ? "E0" : (i == 1) ? "E1" : "E2"); - bp[i] = new Fl_Repeat_Button(x + w - bb / 3, y + (1 + i) * bh, + bp[i] = new Fl_Repeat_Button(x + w - bb / 3, y + (1 + i) * bh, bb / 8, bh / 2, "+"); bm[i] = new Fl_Repeat_Button(x + w - bb / 3, y + (1 + i) * bh + bh / 2, bb / 8, bh / 2, "-"); @@ -881,24 +881,24 @@ projection::projection(fourierProjectionFace *f, int x, int y, int w, int h, group->hide(); } -projectionEditor::projectionEditor() +projectionEditor::projectionEditor() { GModel *m = GModel::current(); - // construct FM_Internals + // construct FM_Internals m->readFourier(); printf("readerSize = %d\n",m->getFMInternals()->getSize()); printf("currentSize = %d\n",m->getFMInternals()->current()->GetNumGroups()); // construct GUI in terms of standard sizes const int width = (int)(3.75 * BB), height = 24 * BH; - + // create all widgets (we construct this once, we never deallocate!) _window = new paletteWindow (width, height, CTX::instance()->nonModalWindows ? true : false, "Reparameterize"); - + new Fl_Box(WB, WB + BH / 2, BB / 2, BH, "Select:"); - + Fl_Group *o = new Fl_Group(WB, WB, 2 * BB, 3 * BH); _select[0] = new Fl_Round_Button(2 * WB + BB / 2, WB, BB, BH, "Points"); _select[1] = new Fl_Round_Button(2 * WB + BB / 2, WB + BH, BB, BH, "Elements"); @@ -912,7 +912,7 @@ projectionEditor::projectionEditor() } o->end(); - { + { Fl_Toggle_Button *b1 = new Fl_Toggle_Button (width - WB - 3 * BB / 2, WB, 3 * BB / 2, BH, "Hide unselected"); b1->callback(proj_hide_cb); @@ -944,13 +944,13 @@ projectionEditor::projectionEditor() int uvw = width - 2 * WB - 2 * hard - 3 * WB; int uvh = height - 7 * WB - 14 * BH - 2 * hard; - _hardEdges[0] = new Fl_Toggle_Button(WB, 3 * WB + 9 * BH + hard, + _hardEdges[0] = new Fl_Toggle_Button(WB, 3 * WB + 9 * BH + hard, hard, uvh); _hardEdges[1] = new Fl_Toggle_Button(width - 4 * WB - hard, 3 * WB + 9 * BH + hard, hard, uvh); - _hardEdges[2] = new Fl_Toggle_Button(WB + hard, 3 * WB + 9 * BH, + _hardEdges[2] = new Fl_Toggle_Button(WB + hard, 3 * WB + 9 * BH, uvw, hard); - _hardEdges[3] = new Fl_Toggle_Button(WB + hard, height - 4 * WB - 5 * BH - hard, + _hardEdges[3] = new Fl_Toggle_Button(WB + hard, height - 4 * WB - 5 * BH - hard, uvw, hard); for(int i = 0; i < 4; i++) _hardEdges[i]->tooltip("Push to mark edge as `hard'"); @@ -965,7 +965,7 @@ projectionEditor::projectionEditor() _slider->callback(filter_cb, this); _slider->tooltip("Filter selection by distance to projection surface"); - _orientation = new Fl_Toggle_Button(width - 3 * WB, height - 4 * WB - 5 * BH - hard, + _orientation = new Fl_Toggle_Button(width - 3 * WB, height - 4 * WB - 5 * BH - hard, 2 * WB, hard); _orientation->callback(filter_cb, this); _orientation->tooltip("Filter elements using orientation"); @@ -986,12 +986,12 @@ projectionEditor::projectionEditor() _modes[0] = new Fl_Value_Input(WB, height - 3 * WB - 4 * BH, BB / 2, BH); _modes[0]->tooltip("Number of Fourier modes along u"); - _modes[1] = new Fl_Value_Input(WB + BB / 2, height - 3 * WB - 4 * BH, BB / 2, BH, + _modes[1] = new Fl_Value_Input(WB + BB / 2, height - 3 * WB - 4 * BH, BB / 2, BH, "Fourier modes"); _modes[1]->tooltip("Number of Fourier modes along v"); _modes[2] = new Fl_Value_Input(WB, height - 3 * WB - 3 * BH, BB / 2, BH); _modes[2]->tooltip("Number of Chebyshev modes along u"); - _modes[3] = new Fl_Value_Input(WB + BB / 2, height - 3 * WB - 3 * BH, BB / 2, BH, + _modes[3] = new Fl_Value_Input(WB + BB / 2, height - 3 * WB - 3 * BH, BB / 2, BH, "Chebyshev modes"); _modes[3]->tooltip("Number of Chebyshev modes along v"); for(int i = 0; i < 4; i++){ @@ -1000,10 +1000,10 @@ projectionEditor::projectionEditor() _modes[i]->minimum(1); _modes[i]->step(1); _modes[i]->align(FL_ALIGN_RIGHT); - } + } { - Fl_Button *b = new Fl_Button(width - WB - BB, height - 3 * WB - 4 * BH, + Fl_Button *b = new Fl_Button(width - WB - BB, height - 3 * WB - 4 * BH, BB, 2 * BH, "Generate\nPatch"); b->callback(compute_cb, this); } @@ -1011,7 +1011,7 @@ projectionEditor::projectionEditor() { int bb = (int)(0.37 * BB); new Fl_Box(WB, height - 2 * WB - 2 * BH, BB / 2, BH, "Delete:"); - Fl_Button *b1 = new Fl_Button(WB + BB / 2, height - 2 * WB - 2 * BH, + Fl_Button *b1 = new Fl_Button(WB + BB / 2, height - 2 * WB - 2 * BH, bb, BH, "last"); b1->callback(action_cb, (void*)"delete_last"); Fl_Button *b2 = new Fl_Button(WB + BB / 2 + bb, height - 2 * WB - 2 * BH, @@ -1038,11 +1038,11 @@ projectionEditor::projectionEditor() } { - Fl_Button *b1 = new Fl_Button(WB, height - WB - BH, BB, BH, + Fl_Button *b1 = new Fl_Button(WB, height - WB - BH, BB, BH, "Blend"); b1->callback(blend_cb, this); - - //Fl_Button *b2 = new Fl_Button(2 * WB + BB, height - WB - BH, BB, + + //Fl_Button *b2 = new Fl_Button(2 * WB + BB, height - WB - BH, BB, // BH, "Intersect"); } @@ -1063,13 +1063,13 @@ void projectionEditor::load(fourierProjectionFace *face, std::string tag) } void projectionEditor::show() -{ - _window->show(); - select_cb(0, this); +{ + _window->show(); + select_cb(0, this); } -int projectionEditor::getSelectionMode() -{ +int projectionEditor::getSelectionMode() +{ if(_select[0]->value()) return ENT_POINT; else diff --git a/Fltk/viewButton.cpp b/Fltk/viewButton.cpp new file mode 100644 index 0000000000000000000000000000000000000000..47ced27f049776f945ee585fb37f8cf6d2cd48a6 --- /dev/null +++ b/Fltk/viewButton.cpp @@ -0,0 +1,335 @@ +// Gmsh - Copyright (C) 1997-2012 C. Geuzaine, J.-F. Remacle +// +// See the LICENSE.txt file for license information. Please report all +// bugs and problems to <gmsh@geuz.org>. + +#include <FL/fl_ask.H> +#include "FlGui.h" +#include "drawContext.h" +#include "fileDialogs.h" +#include "optionWindow.h" +#include "pluginWindow.h" +#include "Context.h" +#include "GModel.h" +#include "PView.h" +#include "PViewData.h" +#include "PViewOptions.h" +#include "Options.h" +#include "OpenFile.h" +#include "Field.h" +#include "OS.h" +#include "onelabGroup.h" +#include "viewButton.h" + +static void view_toggle_cb(Fl_Widget *w, void *data) +{ + int num = (intptr_t)data; + viewButton *but = FlGui::instance()->onelab->getViewButton(num); + if(but){ + opt_view_visible(num, GMSH_SET, but->value()); + drawContext::global()->draw(); + } +} + +static void view_reload(int index) +{ + if(index >= 0 && index < (int)PView::list.size()){ + PView *p = PView::list[index]; + + if(StatFile(p->getData()->getFileName())){ + Msg::Error("File '%s' does not exist", p->getData()->getFileName().c_str()); + return; + } + + int n = PView::list.size(); + + // FIXME: use fileIndex + MergeFile(p->getData()->getFileName()); + + if((int)PView::list.size() > n){ // we loaded a new view + // delete old data and replace with new + delete p->getData(); + p->setData(PView::list.back()->getData()); + PView::list.back()->setData(0); + // delete new view + delete PView::list.back(); + // in case the reloaded view has a different number of time steps + if(p->getOptions()->timeStep > p->getData()->getNumTimeSteps() - 1) + p->getOptions()->timeStep = 0; + p->setChanged(true); + FlGui::instance()->updateViews(); + } + } +} + +static void view_reload_cb(Fl_Widget *w, void *data) +{ + view_reload((intptr_t)data); + drawContext::global()->draw(); +} + +static void view_reload_all_cb(Fl_Widget *w, void *data) +{ + for(unsigned int i = 0; i < PView::list.size(); i++) + view_reload(i); + drawContext::global()->draw(); +} + +static void view_reload_visible_cb(Fl_Widget *w, void *data) +{ + for(unsigned int i = 0; i < PView::list.size(); i++) + if(opt_view_visible(i, GMSH_GET, 0)) + view_reload(i); + drawContext::global()->draw(); +} + +static void view_remove_other_cb(Fl_Widget *w, void *data) +{ + if(PView::list.empty()) return; + for(int i = PView::list.size() - 1; i >= 0; i--) + if(i != (intptr_t)data) delete PView::list[i]; + FlGui::instance()->updateViews(); + drawContext::global()->draw(); +} + +static void view_remove_all_cb(Fl_Widget *w, void *data) +{ + if(PView::list.empty()) return; + int mode = (intptr_t)data; + if(mode == -1){ // remove all + if(PView::list.empty()) return; + while(PView::list.size()) delete PView::list[0]; + } + else if(mode == -2){ // remove all visible + for(int i = PView::list.size() - 1; i >= 0; i--) + if(opt_view_visible(i, GMSH_GET, 0)) delete PView::list[i]; + } + else if(mode == -3){ // remove all invisible + for(int i = PView::list.size() - 1; i >= 0; i--) + if(!opt_view_visible(i, GMSH_GET, 0)) delete PView::list[i]; + } + else if(mode == -4){ // remove all empty + for(int i = PView::list.size() - 1; i >= 0; i--) + if(PView::list[i]->getData()->empty()) delete PView::list[i]; + } + else if(mode >=0 && mode < (int)PView::list.size()){ // remove by name + std::string name = PView::list[mode]->getData()->getName(); + for(int i = PView::list.size() - 1; i >= 0; i--) + if(PView::list[i]->getData()->getName() == name) delete PView::list[i]; + } + + FlGui::instance()->updateViews(); + drawContext::global()->draw(); +} + +static void view_remove_cb(Fl_Widget *w, void *data) +{ + delete PView::list[(intptr_t)data]; + FlGui::instance()->updateViews(); + drawContext::global()->draw(); +} + +#if defined(HAVE_NATIVE_FILE_CHOOSER) +# define TT "\t" +# define NN "\n" +#else +# define TT " (" +# define NN ")\t" +#endif + +static void view_save_cb(Fl_Widget *w, void *data) +{ + static const char *formats = + "Gmsh Parsed" TT "*.pos" NN + "Gmsh Mesh-based" TT "*.pos" NN + "Gmsh Legacy ASCII" TT "*.pos" NN + "Gmsh Legacy Binary" TT "*.pos" NN + "MED" TT "*.rmed" NN + "STL Surface" TT "*.stl" NN + "Generic TXT" TT "*.txt" NN; + + PView *view = PView::list[(intptr_t)data]; + test: + if(fileChooser(FILE_CHOOSER_CREATE, "Save As", formats, + view->getData()->getFileName().c_str())){ + std::string name = fileChooserGetName(1); + if(CTX::instance()->confirmOverwrite) { + if(!StatFile(name)) + if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", + "Cancel", "Replace", 0, name.c_str())) + goto test; + } + int format = 0; + switch(fileChooserGetFilter()){ + case 0: format = 2; break; + case 1: format = 5; break; + case 2: format = 0; break; + case 3: format = 1; break; + case 4: format = 6; break; + case 5: format = 3; break; + case 6: format = 4; break; + } + view->write(name, format); + } +} + +#undef TT +#undef NN + +static void view_alias_cb(Fl_Widget *w, void *data) +{ + new PView(PView::list[(intptr_t)data], false); + FlGui::instance()->updateViews(); + drawContext::global()->draw(); +} + +static void view_alias_with_options_cb(Fl_Widget *w, void *data) +{ + new PView(PView::list[(intptr_t)data], true); + FlGui::instance()->updateViews(); + drawContext::global()->draw(); +} + +static void view_combine_space_all_cb(Fl_Widget *w, void *data) +{ + PView::combine(false, 1, CTX::instance()->post.combineRemoveOrig); + FlGui::instance()->updateViews(); + drawContext::global()->draw(); +} + +static void view_combine_space_visible_cb(Fl_Widget *w, void *data) +{ + PView::combine(false, 0, CTX::instance()->post.combineRemoveOrig); + FlGui::instance()->updateViews(); + drawContext::global()->draw(); +} + +static void view_combine_space_by_name_cb(Fl_Widget *w, void *data) +{ + PView::combine(false, 2, CTX::instance()->post.combineRemoveOrig); + FlGui::instance()->updateViews(); + drawContext::global()->draw(); +} + +static void view_combine_time_all_cb(Fl_Widget *w, void *data) +{ + PView::combine(true, 1, CTX::instance()->post.combineRemoveOrig); + FlGui::instance()->updateViews(); + drawContext::global()->draw(); +} + +static void view_combine_time_visible_cb(Fl_Widget *w, void *data) +{ + PView::combine(true, 0, CTX::instance()->post.combineRemoveOrig); + FlGui::instance()->updateViews(); + drawContext::global()->draw(); +} + +static void view_combine_time_by_name_cb(Fl_Widget *w, void *data) +{ + PView::combine(true, 2, CTX::instance()->post.combineRemoveOrig); + FlGui::instance()->updateViews(); + drawContext::global()->draw(); +} + +static void view_all_visible_cb(Fl_Widget *w, void *data) +{ + int mode = (intptr_t)data; + std::string name; + if(mode >= 0) name = PView::list[mode]->getData()->getName(); + for(unsigned int i = 0; i < PView::list.size(); i++) + opt_view_visible(i, GMSH_SET | GMSH_GUI, + (mode == -1) ? 1 : + (mode == -2) ? 0 : + (mode == -3) ? !opt_view_visible(i, GMSH_GET, 0) : + (name == PView::list[i]->getData()->getName()) ? 1 : + 0); + drawContext::global()->draw(); +} + +static void view_applybgmesh_cb(Fl_Widget *w, void *data) +{ + int index = (intptr_t)data; + if(index >= 0 && index < (int)PView::list.size()) + GModel::current()->getFields()->setBackgroundMesh(index); +} + +viewButton::viewButton(int x, int y, int w, int h, int num) + : Fl_Group(x,y,w,h) +{ + int popw = 4 * FL_NORMAL_SIZE + 3; + + PView *view = PView::list[num]; + PViewData *data = view->getData(); + PViewOptions *opt = view->getOptions(); + + _toggle = new Fl_Light_Button(x, y, w - popw, h); + _toggle->callback(view_toggle_cb, (void *)num); + _toggle->align(FL_ALIGN_INSIDE | FL_ALIGN_CLIP); + _toggle->value(opt->visible); + _toggle->copy_label(data->getName().c_str()); + strcpy(_tooltip, data->getFileName().c_str()); + _toggle->tooltip(_tooltip); + sprintf(_arrow, "[%d]@#-1>", num); + _butt = new Fl_Button(x + w - popw, y, popw, h, _arrow); + _butt->align(FL_ALIGN_RIGHT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); + _butt->tooltip("Show view option menu (Shift+w)"); + + _popup = new Fl_Menu_Button(x + w - popw, y, popw, h); + _popup->type(Fl_Menu_Button::POPUP123); + _popup->add("Reload/View", 'r', + (Fl_Callback *) view_reload_cb, (void *)num, 0); + _popup->add("Reload/Visible Views", 0, + (Fl_Callback *) view_reload_visible_cb, (void *)num, 0); + _popup->add("Reload/All Views", 0, + (Fl_Callback *) view_reload_all_cb, (void *)num, 0); + _popup->add("Remove/View", FL_Delete, + (Fl_Callback *) view_remove_cb, (void *)num, 0); + _popup->add("Remove/Other Views", 0, + (Fl_Callback *) view_remove_other_cb, (void *)num, 0); + _popup->add("Remove/Visible Views", 0, + (Fl_Callback *) view_remove_all_cb, (void *)-2, 0); + _popup->add("Remove/Invisible Views", 0, + (Fl_Callback *) view_remove_all_cb, (void *)-3, 0); + _popup->add("Remove/Empty Views", 0, + (Fl_Callback *) view_remove_all_cb, (void *)-4, 0); + _popup->add("Remove/All Views", 0, + (Fl_Callback *) view_remove_all_cb, (void *)-1, 0); + _popup->add("Remove/By Name", 0, + (Fl_Callback *) view_remove_all_cb, (void *)num, 0); + _popup->add("Alias/View without Options", 0, + (Fl_Callback *) view_alias_cb, (void *)num, 0); + _popup->add("Alias/View with Options", 0, + (Fl_Callback *) view_alias_with_options_cb, (void *)num, 0); + _popup->add("Combine Elements/From Visible Views", 0, + (Fl_Callback *) view_combine_space_visible_cb, (void *)num, 0); + _popup->add("Combine Elements/From All Views", 0, + (Fl_Callback *) view_combine_space_all_cb, (void *)num, 0); + _popup->add("Combine Elements/By View Name", 0, + (Fl_Callback *) view_combine_space_by_name_cb, (void *)num, 0); + _popup->add("Combine Time Steps/From Visible Views", 0, + (Fl_Callback *) view_combine_time_visible_cb, (void *)num, 0); + _popup->add("Combine Time Steps/From All Views", 0, + (Fl_Callback *) view_combine_time_all_cb, (void *)num, 0); + _popup->add("Combine Time Steps/By View Name", 0, + (Fl_Callback *) view_combine_time_by_name_cb, (void *)num, 0); + _popup->add("Set Visibility/All On", 0, + (Fl_Callback *) view_all_visible_cb, (void *)-1, 0); + _popup->add("Set Visibility/All Off", 0, + (Fl_Callback *) view_all_visible_cb, (void *)-2, 0); + _popup->add("Set Visibility/Invert", 0, + (Fl_Callback *) view_all_visible_cb, (void *)-3, 0); + _popup->add("Set Visibility/By name", 0, + (Fl_Callback *) view_all_visible_cb, (void *)num, 0); + _popup->add("Apply As Background Mesh", 0, + (Fl_Callback *) view_applybgmesh_cb, (void *)num, 0); + _popup->add("Save As...", 0, + (Fl_Callback *) view_save_cb, (void *)num, FL_MENU_DIVIDER); + _popup->add("Options", 'o', + (Fl_Callback *) view_options_cb, (void *)num, 0); + _popup->add("Plugins", 'p', + (Fl_Callback *) plugin_cb, (void *)num, 0); + + end(); // close the group + resizable(_toggle); +} diff --git a/Fltk/viewButton.h b/Fltk/viewButton.h new file mode 100644 index 0000000000000000000000000000000000000000..cf97751d4f7efccdb943a17dd56ff0720e5df8ae --- /dev/null +++ b/Fltk/viewButton.h @@ -0,0 +1,29 @@ +// Gmsh - Copyright (C) 1997-2012 C. Geuzaine, J.-F. Remacle +// +// See the LICENSE.txt file for license information. Please report all +// bugs and problems to <gmsh@geuz.org>. + +#ifndef _VIEW_BUTTON_H_ +#define _VIEW_BUTTON_H_ + +#include <string> +#include <FL/Fl.H> +#include <FL/Fl_Group.H> +#include <FL/Fl_Light_Button.H> +#include <FL/Fl_Menu_Button.H> + +class viewButton : public Fl_Group { + private: + Fl_Light_Button *_toggle; + Fl_Button *_butt; + Fl_Menu_Button *_popup; + char _tooltip[256], _arrow[32]; + public: + viewButton(int x, int y, int w, int h, int num); + double value() { return _toggle->value(); } + void value(double val) { _toggle->value(val); } + void copy_label(const std::string &label){ _toggle->copy_label(label.c_str()); } + std::string label(){ return _toggle->label(); } +}; + +#endif diff --git a/Fltk/visibilityWindow.cpp b/Fltk/visibilityWindow.cpp index 3226f62c9678ca4d378c745b280b1445092ada70..39283851f3426372ab49d76ed66c2076a9d0f0cf 100644 --- a/Fltk/visibilityWindow.cpp +++ b/Fltk/visibilityWindow.cpp @@ -466,8 +466,6 @@ class listBrowser : public Fl_Browser{ : Fl_Browser(x, y, w, h, c){} }; -#if defined(HAVE_FL_TREE) - static void _add_vertex(GVertex *gv, Fl_Tree *tree, std::string path) { std::ostringstream vertex; @@ -730,8 +728,6 @@ class treeBrowser : public Fl_Tree{ : Fl_Tree(x, y, w, h, c){} }; -#endif - void visibility_cb(Fl_Widget *w, void *data) { // get the visibility info from the model, and update the browser @@ -743,15 +739,13 @@ void visibility_cb(Fl_Widget *w, void *data) FlGui::instance()->visibility->show(false); _rebuild_list_browser(); -#if defined(HAVE_FL_TREE) _rebuild_tree_browser(false); -#endif FlGui::instance()->visibility->updatePerWindow(true); } static void visibility_save_cb(Fl_Widget *w, void *data) { - Msg::StatusBar(2, true, "Appending visibility info to '%s'...", + Msg::StatusBar(true, "Appending visibility info to '%s'...", GModel::current()->getFileName().c_str()); // get the whole visibility information in geo format std::vector<int> state[4][2]; @@ -803,7 +797,7 @@ static void visibility_save_cb(Fl_Widget *w, void *data) } str += "}\n"; add_infile(str, GModel::current()->getFileName()); - Msg::StatusBar(2, true, "Done appending visibility info"); + Msg::StatusBar(true, "Done appending visibility info"); } static void _set_visibility_by_number(int what, int num, char val, bool recursive, @@ -1063,8 +1057,8 @@ static void visibility_interactive_cb(Fl_Widget *w, void *data) if(what == ENT_ALL) CTX::instance()->mesh.changed = ENT_ALL; drawContext::global()->draw(); - Msg::StatusBar(3, false, "Select %s\n[Press %s'q' to abort]", - str.c_str(), mode ? "" : "'u' to undo or "); + Msg::StatusGl("Select %s\n[Press %s'q' to abort]", + str.c_str(), mode ? "" : "'u' to undo or "); char ib = FlGui::instance()->selectEntity(what); if(ib == 'l') { @@ -1087,7 +1081,7 @@ static void visibility_interactive_cb(Fl_Widget *w, void *data) CTX::instance()->mesh.changed = ENT_ALL; CTX::instance()->pickElements = 0; drawContext::global()->draw(); - Msg::StatusBar(3, false, ""); + Msg::StatusGl(""); } static void visibility_per_window_cb(Fl_Widget *w, void *data) @@ -1220,7 +1214,6 @@ visibilityWindow::visibilityWindow(int deltaFontSize) g->end(); Fl_Group::current()->resizable(g); } -#if defined(HAVE_FL_TREE) { Fl_Group *g = new Fl_Group (WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Tree browser"); @@ -1245,7 +1238,6 @@ visibilityWindow::visibilityWindow(int deltaFontSize) g->resizable(tree); g->end(); } -#endif { Fl_Group *g = new Fl_Group (WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Numeric"); diff --git a/Fltk/visibilityWindow.h b/Fltk/visibilityWindow.h index bcc1823caab469a649a4c665511c9f88014ae1b7..a282df49a00486deace7044b37b0b605cb932efe 100644 --- a/Fltk/visibilityWindow.h +++ b/Fltk/visibilityWindow.h @@ -13,11 +13,7 @@ #include <FL/Fl_Button.H> #include <FL/Fl_Check_Button.H> #include <FL/Fl_Input.H> -#include "GmshConfig.h" - -#if defined(HAVE_FL_TREE) -#include "FL/Fl_Tree.H" -#endif +#include <FL/Fl_Tree.H> class visibilityWindow{ public: @@ -25,10 +21,8 @@ class visibilityWindow{ Fl_Choice *browser_type; Fl_Browser *browser; Fl_Multi_Browser *per_window; -#if defined(HAVE_FL_TREE) Fl_Tree *tree; Fl_Button *tree_create; -#endif Fl_Check_Button *butt[2]; Fl_Button *push[2]; Fl_Input *input[10]; diff --git a/Geo/Curvature.cpp b/Geo/Curvature.cpp index bdde3e6642c79a554ccb11a3732432c63de9470f..9605fda053817dd3c0101051e23a58d154cdafa5 100644 --- a/Geo/Curvature.cpp +++ b/Geo/Curvature.cpp @@ -621,7 +621,7 @@ void Curvature::computeRusinkiewiczNormals() // Pointer to one element MElement *e = face->getMeshElement(iElem); const int E = _ElementToInt[e->getNum()]; - + // Pointers to vertices of triangle MVertex* A = e->getVertex(0); MVertex* B = e->getVertex(1); @@ -865,7 +865,7 @@ void Curvature::computeCurvature(GModel* model, typeOfCurvature typ) _model = model; double t0 = Cpu(); - Msg::StatusBar(2, true, "(C) Computing Curvature"); + Msg::StatusBar(true, "(C) Computing Curvature"); if (typ == RUSIN) computeCurvature_Rusinkiewicz(0); else if (typ == RBF) @@ -874,7 +874,7 @@ void Curvature::computeCurvature(GModel* model, typeOfCurvature typ) computeCurvature_Simple(); double t1 = Cpu(); - Msg::StatusBar(2, true, "(C) Done Computing Curvature (%g s)", t1-t0); + Msg::StatusBar(true, "(C) Done Computing Curvature (%g s)", t1-t0); //writeToMshFile("curvature.msh"); writeToPosFile("curvature.pos"); @@ -1233,7 +1233,7 @@ void Curvature::computeCurvature_RBF() { retrieveCompounds(); initializeMap(); - + //fill set of MVertex std::set<MVertex*> allNodes; for (unsigned int i = 0; i< _EntityArray.size(); ++i) { @@ -1261,10 +1261,10 @@ void Curvature::computeCurvature_RBF() std::vector<MVertex*> _ordered; std::map<MVertex*, double> curvRBF; //GLOBAL - //GRbf *_rbf = new GRbf(sizeBox, 0, 1, _normals, allNodes, _ordered); + //GRbf *_rbf = new GRbf(sizeBox, 0, 1, _normals, allNodes, _ordered); //_rbf->computeCurvature(_rbf->getXYZ(),curvRBF); //LOCAL FD - GRbf *_rbf = new GRbf(sizeBox, 0, 1, _normals, allNodes, _ordered, true); + GRbf *_rbf = new GRbf(sizeBox, 0, 1, _normals, allNodes, _ordered, true); _rbf->computeLocalCurvature(_rbf->getXYZ(),curvRBF); //fill vertex curve @@ -1300,17 +1300,17 @@ void Curvature::triangleNodalValues(MTriangle* triangle, double& c0, double& c1, if ( vertexIterator != _VertexToInt.end() ) V0 = (*vertexIterator).second; else std::cout << "Didn't find vertex with number " << A->getNum() << " in _VertextToInt !" << std::endl; - + vertexIterator = _VertexToInt.find( B->getNum() ); if ( vertexIterator != _VertexToInt.end() ) V1 = (*vertexIterator).second; else std::cout << "Didn't find vertex with number " << B->getNum() << " in _VertextToInt !" << std::endl; - + vertexIterator = _VertexToInt.find( C->getNum() ); if ( vertexIterator != _VertexToInt.end() ) V2 = (*vertexIterator).second; else std::cout << "Didn't find vertex with number " << C->getNum() << " in _VertextToInt !" << std::endl; - + if (isAbs){ c0 = std::abs(_VertexCurve[V0]); //Mean curvature in vertex 0 c1 = std::abs(_VertexCurve[V1]); //Mean curvature in vertex 1 @@ -1405,11 +1405,11 @@ void Curvature::edgeNodalValues(MLine* edge, double& c0, double& c1, int isAbs) vertexIterator = _VertexToInt.find( A->getNum() ); if ( vertexIterator != _VertexToInt.end() ) V0 = (*vertexIterator).second; else std::cout << "Didn't find vertex with number " << A->getNum() << " in _VertextToInt !" << std::endl; - + vertexIterator = _VertexToInt.find( B->getNum() ); if ( vertexIterator != _VertexToInt.end() ) V1 = (*vertexIterator).second; else std::cout << "Didn't find vertex with number " << B->getNum() << " in _VertextToInt !" << std::endl; - + if (isAbs){ c0 = std::abs(_VertexCurve[V0]); //Mean curvature in vertex 0 c1 = std::abs(_VertexCurve[V1]); //Mean curvature in vertex 1 @@ -1484,8 +1484,8 @@ void Curvature::vertexNodalValues(MVertex* A, double& c0, int isAbs) vertexIterator = _VertexToInt.find( A->getNum() ); if ( vertexIterator != _VertexToInt.end() ) V0 = (*vertexIterator).second; else std::cout << "Didn't find vertex with number " << A->getNum() << " in _VertextToInt !" << std::endl; - - + + if (isAbs){ c0 = std::abs(_VertexCurve[V0]); //Mean curvature in vertex 0 } @@ -1497,9 +1497,9 @@ void Curvature::vertexNodalValues(MVertex* A, double& c0, int isAbs) void Curvature::vertexNodalValuesAndDirections(MVertex *A, SVector3* dMax, SVector3* dMin, double* cMax, double* cMin, int isAbs) { - + int V0 = 0; - + std::map<int,int>::iterator vertexIterator; vertexIterator = _VertexToInt.find( A->getNum() ); if ( vertexIterator != _VertexToInt.end() ) V0 = (*vertexIterator).second; @@ -1675,8 +1675,8 @@ void Curvature::writeToPosFile( const std::string & filename) GFace* face = _EntityArray[i]; for (unsigned iElem = 0; iElem < face->getNumMeshElements(); iElem++){ - MElement *e = face->getMeshElement(iElem); - //const int E = _ElementToInt[e->getNum()]; + MElement *e = face->getMeshElement(iElem); + //const int E = _ElementToInt[e->getNum()]; //std::cout << "We are now looking at element Nr: " << E << std::endl; MVertex* A = e->getVertex(0); //Pointers to vertices of triangle @@ -1712,7 +1712,7 @@ void Curvature::writeToPosFile( const std::string & filename) idxelem++; } //Loop over elements - + } // Loop over ptFinalEntityList outfile << "};" << std::endl; diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp index 28231946bfffca78d85056541b91d12982d953a2..544f4b702f7c964794c4f4a4a8892ebdbe17c8b1 100644 --- a/Geo/GModel.cpp +++ b/Geo/GModel.cpp @@ -1416,7 +1416,7 @@ void GModel::checkMeshCoherence(double tolerance) int numEle = getNumMeshElements(); if(!numEle) return; - Msg::StatusBar(2, true, "Checking mesh coherence (%d elements)...", numEle); + Msg::StatusBar(true, "Checking mesh coherence (%d elements)...", numEle); SBoundingBox3d bbox = bounds(); double lc = bbox.empty() ? 1. : norm(SVector3(bbox.max(), bbox.min())); @@ -1469,12 +1469,12 @@ void GModel::checkMeshCoherence(double tolerance) if(num) Msg::Error("%d duplicate element%s", num, num > 1 ? "s" : ""); } - Msg::StatusBar(2, true, "Done checking mesh coherence"); + Msg::StatusBar(true, "Done checking mesh coherence"); } int GModel::removeDuplicateMeshVertices(double tolerance) { - Msg::StatusBar(2, true, "Removing duplicate mesh vertices..."); + Msg::StatusBar(true, "Removing duplicate mesh vertices..."); SBoundingBox3d bbox = bounds(); double lc = bbox.empty() ? 1. : norm(SVector3(bbox.max(), bbox.min())); @@ -1546,7 +1546,7 @@ int GModel::removeDuplicateMeshVertices(double tolerance) if(num) Msg::Info("Removed %d duplicate mesh %s", num, num > 1 ? "vertices" : "vertex"); - Msg::StatusBar(2, true, "Done removing duplicate mesh vertices"); + Msg::StatusBar(true, "Done removing duplicate mesh vertices"); return num; } @@ -1817,7 +1817,7 @@ void GModel::makeDiscreteFacesSimplyConnected() void GModel::createTopologyFromMesh(int ignoreHoles) { - Msg::StatusBar(2, true, "Creating topology from mesh..."); + Msg::StatusBar(true, "Creating topology from mesh..."); double t1 = Cpu(); removeDuplicateMeshVertices(CTX::instance()->geom.tolerance); @@ -1842,7 +1842,7 @@ void GModel::createTopologyFromMesh(int ignoreHoles) exportDiscreteGEOInternals(); double t2 = Cpu(); - Msg::StatusBar(2, true, "Done creating topology from mesh (%g s)", t2 - t1); + Msg::StatusBar(true, "Done creating topology from mesh (%g s)", t2 - t1); } void GModel::createTopologyFromRegions(std::vector<discreteRegion*> &discRegions) diff --git a/Geo/Homology.cpp b/Geo/Homology.cpp index 057a128c411fabcb00bec423a9f7517ee056f403..19c943ac721d9f0420b7bcf24b399d3895b44c3f 100644 --- a/Geo/Homology.cpp +++ b/Geo/Homology.cpp @@ -86,7 +86,7 @@ void Homology::_getElements(const std::vector<GEntity*>& entities, void Homology::_createCellComplex() { - Msg::StatusBar(2, true, "Creating cell complex..."); + Msg::StatusBar(true, "Creating cell complex..."); double t1 = Cpu(); if(_domainEntities.empty()) Msg::Error("Domain is empty"); @@ -117,7 +117,7 @@ void Homology::_createCellComplex() Msg::Error("Cell Complex is empty: check the domain and the mesh"); } double t2 = Cpu(); - Msg::StatusBar(2, true, "Done creating cell complex (%g s)", t2 - t1); + Msg::StatusBar(true, "Done creating cell complex (%g s)", t2 - t1); Msg::Info("%d volumes, %d faces, %d edges, and %d vertices", _cellComplex->getSize(3), _cellComplex->getSize(2), _cellComplex->getSize(1), _cellComplex->getSize(0)); @@ -174,7 +174,7 @@ void Homology::findHomologyBasis(std::vector<int> dim) { if(_cellComplex == NULL) _createCellComplex(); if(_cellComplex->isReduced()) _cellComplex->restoreComplex(); - Msg::StatusBar(2, true, "Reducing cell complex..."); + Msg::StatusBar(true, "Reducing cell complex..."); double t1 = Cpu(); int omitted = _cellComplex->reduceComplex(_combine, _omit); @@ -188,17 +188,17 @@ void Homology::findHomologyBasis(std::vector<int> dim) } double t2 = Cpu(); - Msg::StatusBar(2, true, "Done reducing cell complex (%g s)", t2 - t1); + Msg::StatusBar(true, "Done reducing cell complex (%g s)", t2 - t1); Msg::Info("%d volumes, %d faces, %d edges, and %d vertices", _cellComplex->getSize(3), _cellComplex->getSize(2), _cellComplex->getSize(1), _cellComplex->getSize(0)); - Msg::StatusBar(2, true, "Computing homology space bases ..."); + Msg::StatusBar(true, "Computing homology space bases ..."); t1 = Cpu(); ChainComplex chainComplex = ChainComplex(_cellComplex); chainComplex.computeHomology(); t2 = Cpu(); - Msg::StatusBar(2, true, "Done computing homology space bases (%g s)", t2 - t1); + Msg::StatusBar(true, "Done computing homology space bases (%g s)", t2 - t1); std::string domain = _getDomainString(_domain, _subdomain); _deleteChains(dim); @@ -235,7 +235,7 @@ void Homology::findHomologyBasis(std::vector<int> dim) Msg::Info("H_3 = %d", _betti[3]); if(omitted != 0) Msg::Info("The computation of basis elements in the highest dimension was omitted"); - Msg::StatusBar(2, false, "H_0: %d, H_1: %d, H_2: %d, H_3: %d", + Msg::StatusBar(false, "H_0: %d, H_1: %d, H_2: %d, H_3: %d", _betti[0], _betti[1], _betti[2], _betti[3]); if(dim.empty()) { @@ -253,7 +253,7 @@ void Homology::findCohomologyBasis(std::vector<int> dim) if(_cellComplex == NULL) _createCellComplex(); if(_cellComplex->isReduced()) _cellComplex->restoreComplex(); - Msg::StatusBar(2, true, "Reducing cell complex..."); + Msg::StatusBar(true, "Reducing cell complex..."); double t1 = Cpu(); @@ -270,18 +270,18 @@ void Homology::findCohomologyBasis(std::vector<int> dim) double t2 = Cpu(); - Msg::StatusBar(2, true, "Done reducing cell complex (%g s)", t2 - t1); + Msg::StatusBar(true, "Done reducing cell complex (%g s)", t2 - t1); Msg::Info("%d volumes, %d faces, %d edges, and %d vertices", _cellComplex->getSize(3), _cellComplex->getSize(2), _cellComplex->getSize(1), _cellComplex->getSize(0)); - Msg::StatusBar(2, true, "Computing cohomology space bases ..."); + Msg::StatusBar(true, "Computing cohomology space bases ..."); t1 = Cpu(); ChainComplex chainComplex = ChainComplex(_cellComplex); chainComplex.transposeHMatrices(); chainComplex.computeHomology(true); t2 = Cpu(); - Msg::StatusBar(2, true, "Done computing cohomology space bases (%g s)", t2- t1); + Msg::StatusBar(true, "Done computing cohomology space bases (%g s)", t2- t1); std::string domain = _getDomainString(_domain, _subdomain); _deleteCochains(dim); @@ -318,7 +318,7 @@ void Homology::findCohomologyBasis(std::vector<int> dim) Msg::Info("H^3 = %d", _betti[3]); if(omitted != 0) Msg::Info("The computation of basis elements in the highest dimension was omitted"); - Msg::StatusBar(2, false, "H^0: %d, H^1: %d, H^2: %d, H^3: %d", + Msg::StatusBar(false, "H^0: %d, H^1: %d, H^2: %d, H^3: %d", _betti[0], _betti[1], _betti[2], _betti[3]); if(dim.empty()) { diff --git a/Graphics/drawContext.cpp b/Graphics/drawContext.cpp index c3989ac6d97e847ef11159ac8f8397d1d96b7dc4..03592a7d90aa7826439596cbf1e0c67bd892c030 100644 --- a/Graphics/drawContext.cpp +++ b/Graphics/drawContext.cpp @@ -51,13 +51,11 @@ drawContext::drawContext(drawTransform *transform) _quadric = 0; // cannot create it here: needs valid opengl context _displayLists = 0; - } drawContext::~drawContext() { - if(_quadric) gluDeleteQuadric(_quadric); - if(_displayLists) glDeleteLists(_displayLists, 3); + invalidateQuadricsAndDisplayLists(); } drawContextGlobal *drawContext::global() @@ -66,6 +64,12 @@ drawContextGlobal *drawContext::global() return _global; } +void drawContext::invalidateQuadricsAndDisplayLists() +{ + if(_quadric){ gluDeleteQuadric(_quadric); _quadric = 0; } + if(_displayLists){ glDeleteLists(_displayLists, 3); _displayLists = 0; } +} + void drawContext::createQuadricsAndDisplayLists() { if(!_quadric) _quadric = gluNewQuadric(); @@ -232,22 +236,20 @@ static int needPolygonOffset() void drawContext::draw3d() { - // We can only create this when a valid opengl context exists. (It's - // cheap to create so we just do it at each redraw: this makes it - // much simpler to deal with option changes, e.g. arrow shape - // changes) + // We can only create this when a valid opengl context exists. (It's cheap to + // create so we just do it at each redraw: this makes it much simpler to deal + // with option changes, e.g. arrow shape changes) createQuadricsAndDisplayLists(); - // We should only enable the polygon offset when there is a mix of - // lines and polygons to be drawn; enabling it all the time can lead - // to very small but annoying artifacts in the picture. Since there - // are so many ways in Gmsh to combine polygons and lines - // (geometries + meshes + views...), we do our best here to - // automatically detect if we should enable it. Note: the formula - // for the offset is "offset = factor*DZ+r*units", where DZ is a - // measurement of the change in depth relative to the screen area of - // the polygon, and r is the smallest value that is guaranteed to - // produce a resolvable offset for a given implementation. + // We should only enable the polygon offset when there is a mix of lines and + // polygons to be drawn; enabling it all the time can lead to very small but + // annoying artifacts in the picture. Since there are so many ways in Gmsh to + // combine polygons and lines (geometries + meshes + views...), we do our best + // here to automatically detect if we should enable it. Note: the formula for + // the offset is "offset = factor*DZ+r*units", where DZ is a measurement of + // the change in depth relative to the screen area of the polygon, and r is + // the smallest value that is guaranteed to produce a resolvable offset for a + // given implementation. glPolygonOffset((float)CTX::instance()->polygonOffsetFactor, (float)CTX::instance()->polygonOffsetUnits); if(CTX::instance()->polygonOffsetFactor || CTX::instance()->polygonOffsetUnits) @@ -258,7 +260,6 @@ void drawContext::draw3d() // speedup drawing of textured fonts on cocoa mac version #if defined(HAVE_FLTK) && defined(__APPLE__) && defined(HAVE_64BIT_SIZE_T) -#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3) int numStrings = GModel::current()->getNumVertices(); if(CTX::instance()->mesh.pointsNum) numStrings = std::max(numStrings, GModel::current()->getNumMeshVertices()); @@ -268,7 +269,6 @@ void drawContext::draw3d() numStrings *= 2; if(gl_texture_pile_height() < numStrings) gl_texture_pile_height(numStrings); -#endif #endif glDepthFunc(GL_LESS); @@ -446,10 +446,9 @@ void drawContext::initProjection(int xpick, int ypick, int wpick, int hpick) // no initial translation of the model t_init[0] = t_init[1] = t_init[2] = 0.; - // set up the near and far clipping planes so that the box is large - // enough to manipulate the model and zoom, but not too big - // (otherwise the z-buffer resolution e.g. with Mesa can become - // insufficient) + // set up the near and far clipping planes so that the box is large enough to + // manipulate the model and zoom, but not too big (otherwise the z-buffer + // resolution e.g. with Mesa can become insufficient) double zmax = std::max(fabs(CTX::instance()->min[2]), fabs(CTX::instance()->max[2])); if(zmax < CTX::instance()->lc) zmax = CTX::instance()->lc; @@ -502,10 +501,9 @@ void drawContext::initProjection(int xpick, int ypick, int wpick, int hpick) glDisable(GL_DEPTH_TEST); glPushMatrix(); glLoadIdentity(); - // the z values and the translation are only needed for GL2PS, - // which does not understand "no depth test" (hence we must make - // sure that we draw the background behind the rest of the - // scene) + // the z values and the translation are only needed for GL2PS, which does + // not understand "no depth test" (hence we must make sure that we draw + // the background behind the rest of the scene) glOrtho((double)viewport[0], (double)viewport[2], (double)viewport[1], (double)viewport[3], clip_near, clip_far); @@ -525,9 +523,9 @@ void drawContext::initProjection(int xpick, int ypick, int wpick, int hpick) glLoadIdentity(); } else { - // recenter the model such that the perspective is always at the - // center of gravity (we should maybe add an option to choose - // this, as we do for the rotation center) + // recenter the model such that the perspective is always at the center of + // gravity (we should maybe add an option to choose this, as we do for the + // rotation center) t_init[0] = CTX::instance()->cg[0]; t_init[1] = CTX::instance()->cg[1]; vxmin -= t_init[0]; @@ -610,12 +608,11 @@ void drawContext::initRenderModel() glShadeModel(GL_SMOOTH); - // Normalize the normals automatically. We could use the more - // efficient glEnable(GL_RESCALE_NORMAL) instead (since we initially - // specify unit normals), but GL_RESCALE_NORMAL does only work with - // isotropic scalings (and we allow anistotropic scalings in - // myZoom). Note that GL_RESCALE_NORMAL is only available in - // GL_VERSION_1_2. + // Normalize the normals automatically. We could use the more efficient + // glEnable(GL_RESCALE_NORMAL) instead (since we initially specify unit + // normals), but GL_RESCALE_NORMAL does only work with isotropic scalings (and + // we allow anistotropic scalings in myZoom). Note that GL_RESCALE_NORMAL is + // only available in GL_VERSION_1_2. glEnable(GL_NORMALIZE); // lighting is enabled/disabled for each particular primitive later @@ -648,9 +645,9 @@ void drawContext::initPosition() -CTX::instance()->rotationCenter[1], -CTX::instance()->rotationCenter[2]); - // store the projection and modelview matrices at this precise - // moment (so that we can use them at any later time, even if the - // context has changed, i.e., even if we are out of draw()) + // store the projection and modelview matrices at this precise moment (so that + // we can use them at any later time, even if the context has changed, i.e., + // even if we are out of draw()) glGetDoublev(GL_PROJECTION_MATRIX, proj); glGetDoublev(GL_MODELVIEW_MATRIX, model); @@ -658,9 +655,9 @@ void drawContext::initPosition() glClipPlane((GLenum)(GL_CLIP_PLANE0 + i), CTX::instance()->clipPlane[i]); } -// Takes a cursor position in window coordinates and returns the line -// (given by a point and a unit direction vector), in real space, that -// corresponds to that cursor position +// Takes a cursor position in window coordinates and returns the line (given by +// a point and a unit direction vector), in real space, that corresponds to that +// cursor position void drawContext::unproject(double x, double y, double p[3], double d[3]) { GLint vp[4]; @@ -671,8 +668,8 @@ void drawContext::unproject(double x, double y, double p[3], double d[3]) GLdouble x0, y0, z0, x1, y1, z1; // we use the stored model and proj matrices instead of directly - // getGetDouble'ing the matrices since unproject can be called in or - // after draw2d + // getGetDouble'ing the matrices since unproject can be called in or after + // draw2d if(!gluUnProject(x, y, 0.0, model, proj, vp, &x0, &y0, &z0)) Msg::Warning("unproject1 failed"); if(!gluUnProject(x, y, 1.0, model, proj, vp, &x1, &y1, &z1)) @@ -725,8 +722,8 @@ class hitDepthLessThan{ } }; -// returns the element at a given position in a vertex array (element -// pointers are not always stored: returning 0 is not an error) +// returns the element at a given position in a vertex array (element pointers +// are not always stored: returning 0 is not an error) static MElement *getElement(GEntity *e, int va_type, int index) { switch(va_type){ @@ -756,8 +753,8 @@ bool drawContext::select(int type, bool multiple, bool mesh, regions.clear(); elements.clear(); - // in our case the selection buffer size is equal to between 5 and 7 - // times the maximum number of possible hits + // in our case the selection buffer size is equal to between 5 and 7 times the + // maximum number of possible hits GModel *m = GModel::current(); int eles = (mesh && CTX::instance()->pickElements) ? 4 * m->getNumMeshElements() : 0; int size = 7 * (m->getNumVertices() + m->getNumEdges() + m->getNumFaces() + @@ -799,14 +796,13 @@ bool drawContext::select(int type, bool multiple, bool mesh, for(int i = 0; i < numhits; i++) { // in Gmsh 'names' should always be 0, 2 or 4: // * names == 0 means that there is nothing on the stack - // * if names == 2, the first name is the type of the entity - // (0 for point, 1 for edge, 2 for face or 3 for volume) and - // the second is the entity number; - // * if names == 4, the first name is the type of the entity, - // the second is the entity number, the third is the type - // of vertex array (2 for line, 3 for triangle, 4 for quad) - // and the fourth is the index of the element in the vertex - // array + // * if names == 2, the first name is the type of the entity (0 for point, 1 + // for edge, 2 for face or 3 for volume) and the second is the entity + // number; + // * if names == 4, the first name is the type of the entity, the second is + // the entity number, the third is the type of vertex array (2 for line, 3 + // for triangle, 4 for quad) and the fourth is the index of the element in + // the vertex array GLuint names = *ptr++; *ptr++; // mindepth GLuint maxdepth = *ptr++; @@ -835,9 +831,9 @@ bool drawContext::select(int type, bool multiple, bool mesh, // sort hits to get closest entities first std::sort(hits.begin(), hits.end(), hitDepthLessThan()); - // filter result: if type == ENT_NONE, return the closest entity of - // "lowest dimension" (point < line < surface < volume). Otherwise, - // return the closest entity of type "type" + // filter result: if type == ENT_NONE, return the closest entity of "lowest + // dimension" (point < line < surface < volume). Otherwise, return the closest + // entity of type "type" GLuint typmin = 10; for(unsigned int i = 0; i < hits.size(); i++) typmin = std::min(typmin, hits[i].type); diff --git a/Graphics/drawContext.h b/Graphics/drawContext.h index 42ff998e1f0a6369f15aa8f3f1d8678ca15a3312..37febe748f3d1045917456018cdb1657556fb427 100644 --- a/Graphics/drawContext.h +++ b/Graphics/drawContext.h @@ -79,8 +79,8 @@ class drawTransformScaled : public drawTransform { } }; -// global drawing functions, which need to be redefined for each -// widget toolkit (FLTK, Qt, etc.) +// global drawing functions, which need to be redefined for each widget toolkit +// (FLTK, Qt, etc.) class drawContextGlobal { public: drawContextGlobal(){} @@ -160,6 +160,7 @@ class drawContext { bool isVisible(GModel *m){ return (_hiddenModels.find(m) == _hiddenModels.end()); } bool isVisible(PView *v){ return (_hiddenViews.find(v) == _hiddenViews.end()); } void createQuadricsAndDisplayLists(); + void invalidateQuadricsAndDisplayLists(); void buildRotationMatrix(); void setQuaternion(double p1x, double p1y, double p2x, double p2y); void addQuaternion(double p1x, double p1y, double p2x, double p2y); @@ -264,8 +265,8 @@ class mousePosition { } void recenter(drawContext *ctx) { - // compute the equivalent translation to apply *after* the scaling - // so that the scaling is done around the point which was clicked: + // compute the equivalent translation to apply *after* the scaling so that + // the scaling is done around the point which was clicked: ctx->t[0] = t[0] * (s[0] / ctx->s[0]) - wnr[0] * (1. - (s[0] / ctx->s[0])); ctx->t[1] = t[1] * (s[1] / ctx->s[1]) - wnr[1] * (1. - (s[1] / ctx->s[1])); } diff --git a/Graphics/drawPost.cpp b/Graphics/drawPost.cpp index 1106c665b591b973d2e459080372ba0ddd2be2ec..1b72eb3ec2578bff3ff59d7b53ae31f09d331503 100644 --- a/Graphics/drawPost.cpp +++ b/Graphics/drawPost.cpp @@ -284,7 +284,6 @@ static void drawGlyphs(drawContext *ctx, PView *p) // speedup drawing of textured fonts on cocoa mac version #if defined(HAVE_FLTK) && defined(__APPLE__) && defined(HAVE_64BIT_SIZE_T) -#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3) if(opt->intervalsType == PViewOptions::Numeric){ int numStrings = 0; for(int ent = 0; ent < data->getNumEntities(opt->timeStep); ent++) @@ -292,7 +291,6 @@ static void drawGlyphs(drawContext *ctx, PView *p) if(gl_texture_pile_height() < numStrings) gl_texture_pile_height(numStrings); } -#endif #endif //double xyz[PVIEW_NMAX][3], val[PVIEW_NMAX][9]; diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp index 2115fd90950552d5460b6d08b0d5d7922ca19370..b4d2c14e000f9beb56847a138ec603ec47030187 100644 --- a/Mesh/Generator.cpp +++ b/Mesh/Generator.cpp @@ -358,7 +358,7 @@ static void Mesh0D(GModel *m) static void Mesh1D(GModel *m) { if(TooManyElements(m, 1)) return; - Msg::StatusBar(2, true, "Meshing 1D..."); + Msg::StatusBar(true, "Meshing 1D..."); double t1 = Cpu(); for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); ++it) @@ -383,7 +383,7 @@ static void Mesh1D(GModel *m) double t2 = Cpu(); CTX::instance()->meshTimer[0] = t2 - t1; - Msg::StatusBar(2, true, "Done meshing 1D (%g s)", CTX::instance()->meshTimer[0]); + Msg::StatusBar(true, "Done meshing 1D (%g s)", CTX::instance()->meshTimer[0]); } static void PrintMesh2dStatistics(GModel *m) @@ -441,7 +441,7 @@ static void PrintMesh2dStatistics(GModel *m) static void Mesh2D(GModel *m) { if(TooManyElements(m, 2)) return; - Msg::StatusBar(2, true, "Meshing 2D..."); + Msg::StatusBar(true, "Meshing 2D..."); double t1 = Cpu(); for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it) @@ -520,7 +520,7 @@ static void Mesh2D(GModel *m) double t2 = Cpu(); CTX::instance()->meshTimer[1] = t2 - t1; - Msg::StatusBar(2, true, "Done meshing 2D (%g s)", CTX::instance()->meshTimer[1]); + Msg::StatusBar(true, "Done meshing 2D (%g s)", CTX::instance()->meshTimer[1]); PrintMesh2dStatistics(m); } @@ -535,7 +535,7 @@ static void FindConnectedRegions(std::vector<GRegion*> &delaunay, static void Mesh3D(GModel *m) { if(TooManyElements(m, 3)) return; - Msg::StatusBar(2, true, "Meshing 3D..."); + Msg::StatusBar(true, "Meshing 3D..."); double t1 = Cpu(); // mesh the extruded volumes first @@ -567,46 +567,46 @@ static void Mesh3D(GModel *m) double t2 = Cpu(); CTX::instance()->meshTimer[2] = t2 - t1; - Msg::StatusBar(2, true, "Done meshing 3D (%g s)", CTX::instance()->meshTimer[2]); + Msg::StatusBar(true, "Done meshing 3D (%g s)", CTX::instance()->meshTimer[2]); } void OptimizeMeshNetgen(GModel *m) { - Msg::StatusBar(2, true, "Optimizing 3D mesh with Netgen..."); + Msg::StatusBar(true, "Optimizing 3D mesh with Netgen..."); double t1 = Cpu(); std::for_each(m->firstRegion(), m->lastRegion(), optimizeMeshGRegionNetgen()); double t2 = Cpu(); - Msg::StatusBar(2, true, "Done optimizing 3D mesh with Netgen (%g s)", t2 - t1); + Msg::StatusBar(true, "Done optimizing 3D mesh with Netgen (%g s)", t2 - t1); } void OptimizeMesh(GModel *m) { - Msg::StatusBar(2, true, "Optimizing 3D mesh..."); + Msg::StatusBar(true, "Optimizing 3D mesh..."); double t1 = Cpu(); std::for_each(m->firstRegion(), m->lastRegion(), optimizeMeshGRegionGmsh()); double t2 = Cpu(); - Msg::StatusBar(2, true, "Done optimizing 3D mesh (%g s)", t2 - t1); + Msg::StatusBar(true, "Done optimizing 3D mesh (%g s)", t2 - t1); } void AdaptMesh(GModel *m) { - Msg::StatusBar(2, true, "Adapting 3D mesh..."); + Msg::StatusBar(true, "Adapting 3D mesh..."); double t1 = Cpu(); for(int i = 0; i < 10; i++) std::for_each(m->firstRegion(), m->lastRegion(), adaptMeshGRegion()); double t2 = Cpu(); - Msg::StatusBar(2, true, "Done adaptating 3D mesh (%g s)", t2 - t1); + Msg::StatusBar(true, "Done adaptating 3D mesh (%g s)", t2 - t1); } void RecombineMesh(GModel *m) { - Msg::StatusBar(2, true, "Recombining 2D mesh..."); + Msg::StatusBar(true, "Recombining 2D mesh..."); double t1 = Cpu(); for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it){ @@ -617,7 +617,7 @@ void RecombineMesh(GModel *m) CTX::instance()->mesh.changed = ENT_ALL; double t2 = Cpu(); - Msg::StatusBar(2, true, "Done recombining 2D mesh (%g s)", t2 - t1); + Msg::StatusBar(true, "Done recombining 2D mesh (%g s)", t2 - t1); } //#include <google/profiler.h> diff --git a/Mesh/HighOrder.cpp b/Mesh/HighOrder.cpp index a49a21a27c8d7f8bace4f571653e8a85d40d3a08..8c9d998450c26142865f0bbe79e446e6b3362fdc 100644 --- a/Mesh/HighOrder.cpp +++ b/Mesh/HighOrder.cpp @@ -1021,8 +1021,8 @@ static void setHighOrder(GRegion *gr, edgeContainer &edgeVertices, getEdgeVertices(gr, p, ve, edgeVertices, linear, nPts); if (nPts == 1) { if(incomplete) { - pyramids2.push_back(new MPyramid13(p->getVertex(0), p->getVertex(1), - p->getVertex(2), p->getVertex(3), + pyramids2.push_back(new MPyramid13(p->getVertex(0), p->getVertex(1), + p->getVertex(2), p->getVertex(3), p->getVertex(4), ve[0], ve[1], ve[2], ve[3], ve[4], ve[5], ve[6], ve[7])); } @@ -1080,7 +1080,7 @@ static void setHighOrder(GRegion *gr, edgeContainer &edgeVertices, verts_lvl1[0] = 31; verts_lvl1[1] = 37; verts_lvl1[2] = 40; - verts_lvl1[3] = 34; + verts_lvl1[3] = 34; break; case(2): verts_lvl1[0] = 21; @@ -1104,7 +1104,7 @@ static void setHighOrder(GRegion *gr, edgeContainer &edgeVertices, veq.push_back(ve[verts_lvl3[f]-5]); else if (nPts-q == 3) for (int f = 0; f < 8; f++) - veq.push_back(ve[verts_lvl2[f]-5]); + veq.push_back(ve[verts_lvl2[f]-5]); else if (nPts-q == 2) for (int f = 0; f < 4; f++) veq.push_back(ve[verts_lvl1[f]-5]); @@ -1152,7 +1152,7 @@ static void setHighOrder(GRegion *gr, edgeContainer &edgeVertices, { -0.5, 0.5}, { 0.0, -0.5}, { 0.5, 0.0}, - { 0.0, 0.5}, + { 0.0, 0.5}, { -0.5, 0.0}, { 0.0, 0.0} }; @@ -1454,7 +1454,7 @@ void SetOrderN(GModel *m, int order, bool linear, bool incomplete, bool onlyVisi char msg[256]; sprintf(msg, "Meshing order %d (curvilinear %s)...", order, linear ? "off" : "on"); - Msg::StatusBar(2, true, msg); + Msg::StatusBar(true, msg); double t1 = Cpu(); @@ -1520,7 +1520,7 @@ void SetOrderN(GModel *m, int order, bool linear, bool incomplete, bool onlyVisi checkHighOrderTetrahedron("Volume Mesh", m, bad, worst); // m->writeMSH("CORRECTED.msh"); - Msg::StatusBar(2, true, "Done meshing order %d (%g s)", order, t2 - t1); + Msg::StatusBar(true, "Done meshing order %d (%g s)", order, t2 - t1); } void computeDistanceFromMeshToGeometry (GModel *m, distanceFromMeshToGeometry_t &dist) diff --git a/Mesh/meshPartition.cpp b/Mesh/meshPartition.cpp index 140c57cec0ae77766f9b9ba40f510d07e41b838c..ba28bb81457a44e4a1643f0fa7de22a414f89790 100644 --- a/Mesh/meshPartition.cpp +++ b/Mesh/meshPartition.cpp @@ -65,11 +65,11 @@ extern "C" void METIS_mCPartGraphKway *============================================================================*/ template <typename FaceT> struct LFaceTr; -template <> struct LFaceTr<MEdge> +template <> struct LFaceTr<MEdge> { typedef std::map<MEdge, MElement*, Less_Edge> FaceMap; }; -template <> struct LFaceTr<MFace> +template <> struct LFaceTr<MFace> { typedef std::map<MFace, MElement*, Less_Face> FaceMap; }; @@ -96,7 +96,7 @@ void MakeGraphDIM(const EntIter begin, const EntIter end, const EntIterBE beginBE, const EntIterBE endBE, Graph &graph, BoElemGrVec *const boElemGrVec); - + /******************************************************************************* * * Routine partitionMesh @@ -116,15 +116,15 @@ void MakeGraphDIM(const EntIter begin, const EntIter end, * ******************************************************************************/ -int RenumberMesh(GModel *const model, meshPartitionOptions &options, +int RenumberMesh(GModel *const model, meshPartitionOptions &options, std::vector<MElement*> &numbered) { Graph graph; BoElemGrVec boElemGrVec; int ier; - Msg::StatusBar(2, true, "Building graph..."); + Msg::StatusBar(true, "Building graph..."); ier = MakeGraph(model, graph, options, &boElemGrVec); - Msg::StatusBar(2, true, "Renumbering graph..."); + Msg::StatusBar(true, "Renumbering graph..."); if(!ier) ier = RenumberGraph(graph, options); if(ier) return 1; @@ -136,7 +136,7 @@ int RenumberMesh(GModel *const model, meshPartitionOptions &options, numbered[graph.partition[i]-1] = graph.element[i]; } - Msg::StatusBar(2, true, "Done renumbering graph"); + Msg::StatusBar(true, "Done renumbering graph"); return 0; } @@ -148,23 +148,23 @@ int PartitionMeshElements(std::vector<MElement*> &elements, meshPartitionOptions for (unsigned i=0;i<elements.size();++i) for (int j=0;j<elements[i]->getNumVertices();j++) setv.insert(elements[i]->getVertex(j)); - + for (std::set<MVertex* >::iterator it = setv.begin(); it != setv.end(); it++) gf->mesh_vertices.push_back(*it); - + for (std::vector<MElement* >::iterator it = elements.begin(); it != elements.end(); it++){ - if ((*it)->getType() == TYPE_TRI) + if ((*it)->getType() == TYPE_TRI) gf->triangles.push_back((MTriangle*)(*it)); - else if ((*it)->getType() == TYPE_QUA) + else if ((*it)->getType() == TYPE_QUA) gf->quadrangles.push_back((MQuadrangle*)(*it)); } tmp_model->add(gf); - - PartitionMesh(tmp_model,options); - + + PartitionMesh(tmp_model,options); + tmp_model->remove(gf); delete tmp_model; - + return 1; } @@ -173,9 +173,9 @@ int PartitionMeshFace(std::list<GFace*> &cFaces, meshPartitionOptions &options) GModel *tmp_model = new GModel(); for(std::list<GFace*>::iterator it = cFaces.begin(); it != cFaces.end(); it++) tmp_model->add(*it); - - PartitionMesh(tmp_model,options); - + + PartitionMesh(tmp_model,options); + for(std::list<GFace*>::iterator it = cFaces.begin(); it != cFaces.end(); it++) tmp_model->remove(*it); delete tmp_model; @@ -196,13 +196,13 @@ int RenumberMeshElements(std::vector<MElement*> &elements, meshPartitionOptions for (std::set<MVertex* >::iterator it = setv.begin(); it != setv.end(); it++) gf->mesh_vertices.push_back(*it); for (std::vector<MElement* >::iterator it = elements.begin(); it != elements.end(); it++){ - if ((*it)->getType() == TYPE_TRI) + if ((*it)->getType() == TYPE_TRI) gf->triangles.push_back((MTriangle*)(*it)); - else if ((*it)->getType() == TYPE_QUA) + else if ((*it)->getType() == TYPE_QUA) gf->quadrangles.push_back((MQuadrangle*)(*it)); } tmp_model->add(gf); - RenumberMesh(tmp_model, options, elements); + RenumberMesh(tmp_model, options, elements); tmp_model->remove(gf); } else if (elements[0]->getDim() == 3){ @@ -210,13 +210,13 @@ int RenumberMeshElements(std::vector<MElement*> &elements, meshPartitionOptions for (std::set<MVertex* >::iterator it = setv.begin(); it != setv.end(); it++) gr->mesh_vertices.push_back(*it); for (std::vector<MElement* >::iterator it = elements.begin(); it != elements.end(); it++){ - if ((*it)->getType() == TYPE_TET) + if ((*it)->getType() == TYPE_TET) gr->tetrahedra.push_back((MTetrahedron*)(*it)); - else if ((*it)->getType() == TYPE_HEX) + else if ((*it)->getType() == TYPE_HEX) gr->hexahedra.push_back((MHexahedron*)(*it)); - else if ((*it)->getType() == TYPE_PRI) + else if ((*it)->getType() == TYPE_PRI) gr->prisms.push_back((MPrism*)(*it)); - else if ((*it)->getType() == TYPE_PYR) + else if ((*it)->getType() == TYPE_PYR) gr->pyramids.push_back((MPyramid*)(*it)); } tmp_model->add(gr); @@ -225,7 +225,7 @@ int RenumberMeshElements(std::vector<MElement*> &elements, meshPartitionOptions return 1; } -int RenumberMesh(GModel *const model, meshPartitionOptions &options) +int RenumberMesh(GModel *const model, meshPartitionOptions &options) { for (GModel::fiter it = model->firstFace() ; it != model->lastFace() ; ++it){ std::vector<MElement *> temp; @@ -249,14 +249,14 @@ int RenumberMesh(GModel *const model, meshPartitionOptions &options) temp.insert(temp.begin(), (*it)->tetrahedra.begin(), (*it)->tetrahedra.end()); RenumberMeshElements(temp, options); (*it)->tetrahedra.clear(); - for (unsigned int i = 0; i < temp.size(); i++) + for (unsigned int i = 0; i < temp.size(); i++) (*it)->tetrahedra.push_back((MTetrahedron*)temp[i]); temp.clear(); temp.insert(temp.begin(),(*it)->hexahedra.begin(),(*it)->hexahedra.end()); RenumberMeshElements(temp, options); (*it)->hexahedra.clear(); - for (unsigned int i = 0; i < temp.size(); i++) + for (unsigned int i = 0; i < temp.size(); i++) (*it)->hexahedra.push_back((MHexahedron*)temp[i]); } return 1; @@ -267,12 +267,12 @@ int PartitionMesh(GModel *const model, meshPartitionOptions &options) Graph graph; BoElemGrVec boElemGrVec; int ier; - Msg::StatusBar(2, true, "Building graph..."); + Msg::StatusBar(true, "Building graph..."); ier = MakeGraph(model, graph, options, &boElemGrVec); - Msg::StatusBar(2, true, "Partitioning graph..."); + Msg::StatusBar(true, "Partitioning graph..."); if(!ier) ier = PartitionGraph(graph, options); if(ier) return 1; - + // Count partition sizes and assign partitions to internal elements std::vector<int> ssize(options.num_partitions, 0); const int n = graph.getNumVertex(); @@ -299,7 +299,7 @@ int PartitionMesh(GModel *const model, meshPartitionOptions &options) if (options.createPartitionBoundaries || options.createGhostCells) CreatePartitionBoundaries (model, options.createGhostCells); - Msg::StatusBar(2, true, "Done partitioning graph"); + Msg::StatusBar(true, "Done partitioning graph"); return 0; } @@ -506,7 +506,7 @@ int RenumberGraph(Graph &graph, meshPartitionOptions &options) const int iSec = 0; int options = 0; int *perm = new int[n]; - METIS_NodeND(&n, + METIS_NodeND(&n, &graph.xadj[graph.section[iSec]], &graph.adjncy[graph.section[iSec]], &numflag,&options,perm,&graph.partition[graph.section[iSec]]); delete [] perm; @@ -568,7 +568,7 @@ int MakeGraph(GModel *const model, Graph &graph, meshPartitionOptions &options, /*--------------------------------------------------------------------* * Make a graph for the entire domain *--------------------------------------------------------------------*/ - + //--Get the dimension of the mesh and count the numbers of elements unsigned numElem[5]; @@ -590,7 +590,7 @@ int MakeGraph(GModel *const model, Graph &graph, meshPartitionOptions &options, // maximum possible number of corresponding edges for the mesh const int maxGrEdge = (numElem[ElemTypeTri]*3 + numElem[ElemTypeQuad]*4 + numElem[ElemTypePolyg]*4)/2; - + graph.allocate(numGrVert, maxGrEdge); // Make the graph MakeGraphDIM<2>(model->firstFace(), model->lastFace(), @@ -630,7 +630,7 @@ int MakeGraph(GModel *const model, Graph &graph, meshPartitionOptions &options, } // break; - + // case PartitionByPhysical: // { @@ -721,7 +721,7 @@ int MakeGraph(GModel *const model, Graph &graph, meshPartitionOptions &options, // (numElem[ElemTypeTetra]*4 + numElem[ElemTypeHexa]*6 + // (numElem[ElemTypePrism] + numElem[ElemTypePyramid])*5)/2; // graph.allocate(numGrVert, maxGrEdge); - + // // Make the graph // for(PhysGroupMap::iterator itPhys = groups[region].begin(); // itPhys != groups[region].end(); ++itPhys) { @@ -760,9 +760,9 @@ void MakeGraphDIM(const EntIter begin, const EntIter end, typedef typename DimTr<DIM>::FaceT FaceT; typedef typename LFaceTr<FaceT>::FaceMap FaceMap; - + graph.markSection(); - + FaceMap faceMap; GrVertexMap grVertMap; @@ -881,7 +881,7 @@ struct MatchBoElemToGrVertex { typedef typename DimTr<DIM>::FaceT FaceT; // The type/dimension of face typedef typename LFaceTr<FaceT>::FaceMap FaceMap; // The corresponding map - + static void eval(const GEntity *const entity, const FaceMap &faceMap, const GrVertexMap &grVertMap, const Graph &graph, std::vector<BoElemGr> &boElemGrVec) @@ -967,7 +967,7 @@ void assignPartitionBoundary(GModel *model, MFace &me, if (!found)v2.push_back(v[i]->getPartition()); } if (v2.size() < 2)return; - + partitionFace pe(model, 1, v2); std::set<partitionFace*, Less_partitionFace>::iterator it = pfaces.find(&pe); partitionFace *ppe; @@ -1012,7 +1012,7 @@ void assignPartitionBoundary(GModel *model, partitionFace pf(model, 1, v2); std::set<partitionFace*, Less_partitionFace>::iterator itf = pfaces.find(&pf); if (itf != pfaces.end())return; - + partitionEdge pe (model, 1, 0, 0, v2); std::set<partitionEdge*, Less_partitionEdge>::iterator it = pedges.find(&pe); partitionEdge *ppe; @@ -1036,7 +1036,7 @@ void splitBoundaryEdges(GModel *model, std::set<partitionEdge*, Less_partition for (unsigned int i = 0; i < ge->lines.size(); i++){ segments.push_back(ge->lines[i]); } - + while (!segments.empty()) { std::vector<MLine*> myLines; std::list<MLine*>::iterator it = segments.begin(); @@ -1046,7 +1046,7 @@ void splitBoundaryEdges(GModel *model, std::set<partitionEdge*, Less_partition segments.erase(it); it++; for (int i=0; i<2; i++) { - for (std::list<MLine*>::iterator it = segments.begin() ; it != segments.end(); ++it){ + for (std::list<MLine*>::iterator it = segments.begin() ; it != segments.end(); ++it){ MVertex *v1 = (*it)->getVertex(0); MVertex *v2 = (*it)->getVertex(1); std::list<MLine*>::iterator itp; @@ -1074,7 +1074,7 @@ void splitBoundaryEdges(GModel *model, std::set<partitionEdge*, Less_partition vB = vE; vE = temp; } - if (nbSplit == 0 && segments.empty()) break; + if (nbSplit == 0 && segments.empty()) break; int numEdge = model->getMaxElementaryNumber(1) + 1; discreteEdge *newGe = new discreteEdge(model, numEdge, 0, 0); newGe->lines.insert(newGe->lines.end(), myLines.begin(), myLines.end()); @@ -1082,11 +1082,11 @@ void splitBoundaryEdges(GModel *model, std::set<partitionEdge*, Less_partition newGe->orderMLines(); //this creates also mesh_vertices nbSplit++; - printf("*** split partitionEdge with tag =%d\n", numEdge); + printf("*** split partitionEdge with tag =%d\n", numEdge); } if (nbSplit > 0) model->remove(ge); } - + return; } @@ -1111,7 +1111,7 @@ void assignPartitionBoundary(GModel *model, if (!found)v2.push_back(v[i]->getPartition()); } if (v2.size() < 2)return; - + partitionFace pf(model, 1, v2); std::set<partitionFace*, Less_partitionFace>::iterator itf = pfaces.find(&pf); if (itf != pfaces.end()) return; @@ -1132,8 +1132,8 @@ void assignPartitionBoundary(GModel *model, ppv->points.push_back(new MPoint (ve)); } -static void addGhostCells(GEntity *ge, - std::multimap<MVertex*, MElement*> &vertexToElement, +static void addGhostCells(GEntity *ge, + std::multimap<MVertex*, MElement*> &vertexToElement, std::multimap<MElement*, short> &ghosts) { // get all the nodes on the partition boundary (we need to recompute @@ -1144,7 +1144,7 @@ static void addGhostCells(GEntity *ge, for(int j = 0; j < e->getNumVertices(); j++) verts.insert(e->getVertex(j)); } - + // get all the elements that touch these nodes for(std::set<MVertex*>::iterator it = verts.begin(); it != verts.end(); it++){ std::pair<std::multimap<MVertex*, MElement*>::iterator, @@ -1193,7 +1193,7 @@ int CreatePartitionBoundaries(GModel *model, bool createGhostCells, bool createA std::multimap<MFace, MElement*, Less_Face> faceToElement; std::multimap<MEdge, MElement*, Less_Edge> edgeToElement; std::multimap<MVertex*, MElement*> vertexToElement; - + // create partition faces if (meshDim == 3){ for(GModel::riter it = model->firstRegion(); it != model->lastRegion(); ++it){ @@ -1202,7 +1202,7 @@ int CreatePartitionBoundaries(GModel *model, bool createGhostCells, bool createA fillit_(faceToElement, (*it)->prisms.begin(), (*it)->prisms.end()); fillit_(faceToElement, (*it)->pyramids.begin(), (*it)->pyramids.end()); fillit_(faceToElement, (*it)->polyhedra.begin(), (*it)->polyhedra.end()); - } + } std::multimap<MFace, MElement*, Less_Face>::iterator it = faceToElement.begin(); Equal_Face oper; while (it != faceToElement.end()){ @@ -1216,7 +1216,7 @@ int CreatePartitionBoundaries(GModel *model, bool createGhostCells, bool createA assignPartitionBoundary(model, e, pfaces, voe); } } - + // create partition edges if (meshDim > 1){ if (meshDim == 2 || createAllDims){ @@ -1233,7 +1233,7 @@ int CreatePartitionBoundaries(GModel *model, bool createGhostCells, bool createA fillit_(edgeToElement, (*it)->prisms.begin(), (*it)->prisms.end()); fillit_(edgeToElement, (*it)->pyramids.begin(), (*it)->pyramids.end()); fillit_(edgeToElement, (*it)->polyhedra.begin(), (*it)->polyhedra.end()); - } + } } std::multimap<MEdge, MElement*, Less_Edge>::iterator it = edgeToElement.begin(); Equal_Edge oper; @@ -1267,7 +1267,7 @@ int CreatePartitionBoundaries(GModel *model, bool createGhostCells, bool createA fillit_(vertexToElement, (*it)->pyramids.begin(), (*it)->pyramids.end()); fillit_(vertexToElement, (*it)->polyhedra.begin(), (*it)->polyhedra.end()); } - } + } std::multimap<MVertex*, MElement*>::iterator it = vertexToElement.begin(); while (it != vertexToElement.end()){ MVertex *v = it->first; @@ -1299,7 +1299,7 @@ int CreatePartitionBoundaries(GModel *model, bool createGhostCells, bool createA return 1; } -void createPartitionFaces(GModel *model, std::vector<MElement *> &elements, int N, +void createPartitionFaces(GModel *model, std::vector<MElement *> &elements, int N, std::vector<discreteFace*> &discreteFaces) { #if defined(HAVE_SOLVER) @@ -1318,21 +1318,21 @@ void createPartitionFaces(GModel *model, std::vector<MElement *> &elements, int for(unsigned int i = 0; i < elements.size(); ++i){ MElement *e = elements[i]; int part = e->getPartition()-1; - for(int j = 0; j < 3; j++){ + for(int j = 0; j < 3; j++){ allNodes[part].insert(e->getVertex(j)); } discreteFaces[part]->triangles.push_back(new MTriangle(e->getVertex(0),e->getVertex(1),e->getVertex(2))) ; } for(int i = 0; i < N; i++){ - for (std::set<MVertex*>::iterator it = allNodes[i].begin(); it != allNodes[i].end(); it++){ + for (std::set<MVertex*>::iterator it = allNodes[i].begin(); it != allNodes[i].end(); it++){ discreteFaces[i]->mesh_vertices.push_back(*it); } } - + #endif } - + /******************************************************************************* * * Explicit instantiations of routine MakeGraphDIM diff --git a/Mesh/meshRefine.cpp b/Mesh/meshRefine.cpp index 75cab94456e9c4775201933eca26a8bdb36fd4f7..0fdb2d2d076848a9a923d8a41f38d835cec8a4c6 100644 --- a/Mesh/meshRefine.cpp +++ b/Mesh/meshRefine.cpp @@ -45,7 +45,7 @@ static void Subdivide(GEdge *ge) ge->lines = lines2; // 2nd order meshing destroyed the ordering of the vertices on the edge - std::sort(ge->mesh_vertices.begin(), ge->mesh_vertices.end(), + std::sort(ge->mesh_vertices.begin(), ge->mesh_vertices.end(), MVertexLessThanParam()); for(unsigned int i = 0; i < ge->mesh_vertices.size(); i++) ge->mesh_vertices[i]->setPolynomialOrder(1); @@ -105,7 +105,7 @@ static void Subdivide(GFace *gf, bool splitIntoQuads, bool splitIntoHexas, } MVertex *newv; if (reparamOK){ - GPoint gp = gf->point(pt); + GPoint gp = gf->point(pt); newv = new MFaceVertex(gp.x(), gp.y(), gp.z(), gf, pt[0], pt[1]); } else { @@ -159,7 +159,7 @@ static void Subdivide(GRegion *gr, bool splitIntoHexas, faceContainer &faceVerti } gr->tetrahedra = tetrahedra2; } - + std::vector<MHexahedron*> hexahedra2; for(unsigned int i = 0; i < gr->hexahedra.size(); i++){ MHexahedron *h = gr->hexahedra[i]; @@ -273,40 +273,40 @@ static void Subdivide(GRegion *gr, bool splitIntoHexas, faceContainer &faceVerti } gr->hexahedra = hexahedra2; - + std::vector<MPrism*> prisms2; for(unsigned int i = 0; i < gr->prisms.size(); i++){ MPrism *p = gr->prisms[i]; if(p->getNumVertices() == 18){ prisms2.push_back - (new MPrism(p->getVertex(0), p->getVertex(6), p->getVertex(7), + (new MPrism(p->getVertex(0), p->getVertex(6), p->getVertex(7), p->getVertex(8), p->getVertex(15), p->getVertex(16))); prisms2.push_back - (new MPrism(p->getVertex(8), p->getVertex(15), p->getVertex(16), - p->getVertex(3), p->getVertex(12), p->getVertex(13))); + (new MPrism(p->getVertex(8), p->getVertex(15), p->getVertex(16), + p->getVertex(3), p->getVertex(12), p->getVertex(13))); prisms2.push_back - (new MPrism(p->getVertex(6), p->getVertex(1), p->getVertex(9), - p->getVertex(15), p->getVertex(10), p->getVertex(17))); + (new MPrism(p->getVertex(6), p->getVertex(1), p->getVertex(9), + p->getVertex(15), p->getVertex(10), p->getVertex(17))); prisms2.push_back - (new MPrism(p->getVertex(15), p->getVertex(10), p->getVertex(17), - p->getVertex(12), p->getVertex(4), p->getVertex(14))); + (new MPrism(p->getVertex(15), p->getVertex(10), p->getVertex(17), + p->getVertex(12), p->getVertex(4), p->getVertex(14))); prisms2.push_back - (new MPrism(p->getVertex(7), p->getVertex(9), p->getVertex(2), - p->getVertex(16), p->getVertex(17), p->getVertex(11))); + (new MPrism(p->getVertex(7), p->getVertex(9), p->getVertex(2), + p->getVertex(16), p->getVertex(17), p->getVertex(11))); prisms2.push_back - (new MPrism(p->getVertex(16), p->getVertex(17), p->getVertex(11), - p->getVertex(13), p->getVertex(14), p->getVertex(5))); + (new MPrism(p->getVertex(16), p->getVertex(17), p->getVertex(11), + p->getVertex(13), p->getVertex(14), p->getVertex(5))); prisms2.push_back - (new MPrism(p->getVertex(9), p->getVertex(7), p->getVertex(6), - p->getVertex(17), p->getVertex(16), p->getVertex(15))); + (new MPrism(p->getVertex(9), p->getVertex(7), p->getVertex(6), + p->getVertex(17), p->getVertex(16), p->getVertex(15))); prisms2.push_back - (new MPrism(p->getVertex(17), p->getVertex(16), p->getVertex(15), + (new MPrism(p->getVertex(17), p->getVertex(16), p->getVertex(15), p->getVertex(14), p->getVertex(13), p->getVertex(12))); - } + } delete p; } gr->prisms = prisms2; - + std::vector<MPyramid*> pyramids2; for(unsigned int i = 0; i < gr->pyramids.size(); i++){ if(splitIntoHexas){ @@ -317,31 +317,31 @@ static void Subdivide(GRegion *gr, bool splitIntoHexas, faceContainer &faceVerti if(p->getNumVertices() == 14){ // Base pyramids2.push_back - (new MPyramid(p->getVertex(0), p->getVertex(5), p->getVertex(13), + (new MPyramid(p->getVertex(0), p->getVertex(5), p->getVertex(13), p->getVertex(6), p->getVertex(7))); pyramids2.push_back - (new MPyramid(p->getVertex(5), p->getVertex(1), p->getVertex(8), + (new MPyramid(p->getVertex(5), p->getVertex(1), p->getVertex(8), p->getVertex(13), p->getVertex(9))); pyramids2.push_back - (new MPyramid(p->getVertex(13), p->getVertex(8), p->getVertex(2), + (new MPyramid(p->getVertex(13), p->getVertex(8), p->getVertex(2), p->getVertex(10), p->getVertex(11))); pyramids2.push_back (new MPyramid(p->getVertex(6), p->getVertex(13), p->getVertex(10), p->getVertex(3), p->getVertex(12))); - + // Split remaining into tets // Top gr->tetrahedra.push_back ((new MTetrahedron(p->getVertex(7), p->getVertex(9), p->getVertex(12), p->getVertex(4)))); gr->tetrahedra.push_back ((new MTetrahedron(p->getVertex(9), p->getVertex(11), p->getVertex(12), p->getVertex(4)))); - + // Upside down one gr->tetrahedra.push_back ((new MTetrahedron(p->getVertex(9), p->getVertex(12), p->getVertex(11), p->getVertex(13)))); gr->tetrahedra.push_back ((new MTetrahedron(p->getVertex(7), p->getVertex(12), p->getVertex(9), p->getVertex(13)))); - + // Four tets around bottom perimeter gr->tetrahedra.push_back ((new MTetrahedron(p->getVertex(7), p->getVertex(9), p->getVertex(5), p->getVertex(13)))); @@ -363,9 +363,9 @@ static void Subdivide(GRegion *gr, bool splitIntoHexas, faceContainer &faceVerti void RefineMesh(GModel *m, bool linear, bool splitIntoQuads, bool splitIntoHexas) { - Msg::StatusBar(2, true, "Refining mesh..."); + Msg::StatusBar(true, "Refining mesh..."); double t1 = Cpu(); - + // Create 2nd order mesh (using "2nd order complete" elements) to // generate vertex positions SetOrderN(m, 2, linear, false); @@ -389,5 +389,5 @@ void RefineMesh(GModel *m, bool linear, bool splitIntoQuads, bool splitIntoHexas double t2 = Cpu(); - Msg::StatusBar(2, true, "Done refining mesh (%g s)", t2 - t1); + Msg::StatusBar(true, "Done refining mesh (%g s)", t2 - t1); } diff --git a/Parser/Gmsh.tab.cpp b/Parser/Gmsh.tab.cpp index 88f6b84c650406e7aaa6d2702fde3cab3d63fbe4..1a5e50790397b439e655ce7da716de47c22421aa 100644 --- a/Parser/Gmsh.tab.cpp +++ b/Parser/Gmsh.tab.cpp @@ -7106,7 +7106,7 @@ yyreduce: { if(!strcmp((yyvsp[(1) - (3)].c), "Include")){ std::string tmp = FixRelativePath(gmsh_yyname, (yyvsp[(2) - (3)].c)); - Msg::StatusBar(2, true, "Reading '%s'...", tmp.c_str()); + Msg::StatusBar(true, "Reading '%s'...", tmp.c_str()); // Warning: we explicitly ask ParseFile not to fclose() the included // file, in order to allow user functions definitions in these files. // The files will be closed in the next time OpenFile terminates. If @@ -7117,7 +7117,7 @@ yyreduce: // instead of using the FILE pointer...) ParseFile(tmp, false, true); SetBoundingBox(); - Msg::StatusBar(2, true, "Done reading '%s'", tmp.c_str()); + Msg::StatusBar(true, "Done reading '%s'", tmp.c_str()); } else if(!strcmp((yyvsp[(1) - (3)].c), "Print")){ // make sure we have the latest data from GEO_Internals in GModel @@ -10579,7 +10579,7 @@ int PrintListOfDouble(char *format, List_T *list, char *buffer) // if format does not contain formatting characters, dump the list (useful for // quick debugging of lists) int numFormats = 0; - for(int i = 0; i < strlen(format); i++) + for(unsigned int i = 0; i < strlen(format); i++) if(format[i] == '%') numFormats++; if(!numFormats){ strcpy(buffer, format); diff --git a/Parser/Gmsh.y b/Parser/Gmsh.y index 45aeb4fcfbe3f22fed53002409f200c5aba785a2..e1767323c15d765a8134232b5163a6f0e02d0684 100644 --- a/Parser/Gmsh.y +++ b/Parser/Gmsh.y @@ -2535,7 +2535,7 @@ Command : { if(!strcmp($1, "Include")){ std::string tmp = FixRelativePath(gmsh_yyname, $2); - Msg::StatusBar(2, true, "Reading '%s'...", tmp.c_str()); + Msg::StatusBar(true, "Reading '%s'...", tmp.c_str()); // Warning: we explicitly ask ParseFile not to fclose() the included // file, in order to allow user functions definitions in these files. // The files will be closed in the next time OpenFile terminates. If @@ -2546,7 +2546,7 @@ Command : // instead of using the FILE pointer...) ParseFile(tmp, false, true); SetBoundingBox(); - Msg::StatusBar(2, true, "Done reading '%s'", tmp.c_str()); + Msg::StatusBar(true, "Done reading '%s'", tmp.c_str()); } else if(!strcmp($1, "Print")){ // make sure we have the latest data from GEO_Internals in GModel diff --git a/Post/PViewIO.cpp b/Post/PViewIO.cpp index 371eb71c1561bfcb67be9ad3a1154735bf42b45e..63eb8e4d7ec98aed4115f4ca0a53f8e3a05c58f8 100644 --- a/Post/PViewIO.cpp +++ b/Post/PViewIO.cpp @@ -300,7 +300,7 @@ bool PView::readMED(const std::string &fileName, int fileIndex) bool PView::write(const std::string &fileName, int format, bool append) { - Msg::StatusBar(2, true, "Writing '%s'...", fileName.c_str()); + Msg::StatusBar(true, "Writing '%s'...", fileName.c_str()); bool ret; switch(format){ @@ -329,6 +329,6 @@ bool PView::write(const std::string &fileName, int format, bool append) default: ret = false; Msg::Error("Unknown view format %d", format); break; } - if(ret) Msg::StatusBar(2, true, "Done writing '%s'", fileName.c_str()); + if(ret) Msg::StatusBar(true, "Done writing '%s'", fileName.c_str()); return ret; } diff --git a/README.txt b/README.txt index 4e458c43a43e3e19078a6f255cc90ba414ea0df7..c9654a6b9f7c18d07643fa23605bc54d2df1393f 100644 --- a/README.txt +++ b/README.txt @@ -10,9 +10,8 @@ is located in doc/texinfo/. See the demos/ directory and the web site http://geuz.org/gmsh for additional examples. Building Gmsh from its source code requires a C++ compiler and CMake -(http://cmake.org). Building the graphical user interface requires FLTK 1.1.7 -or above (http://fltk.org), configured with OpenGL support. Building the 64 bit -graphical version on MacOS X requires FLTK 1.3. +(http://cmake.org). Building the graphical user interface requires FLTK 1.3 +(http://fltk.org), configured with OpenGL support. Build Gmsh using CMake's graphical user interface diff --git a/contrib/Fl_Tree/CMakeLists.txt b/contrib/Fl_Tree/CMakeLists.txt deleted file mode 100644 index 0337353f64ace2729f2ad26eb9fecbd38fa781ad..0000000000000000000000000000000000000000 --- a/contrib/Fl_Tree/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -# Gmsh - Copyright (C) 1997-2012 C. Geuzaine, J.-F. Remacle -# -# See the LICENSE.txt file for license information. Please report all -# bugs and problems to <gmsh@geuz.org>. - -set(SRC - Fl_Tree.cxx - Fl_Tree_Item.cxx - Fl_Tree_Item_Array.cxx - Fl_Tree_Prefs.cxx -) - -file(GLOB_RECURSE HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.H) -append_gmsh_src(contrib/Fl_Tree "${SRC};${HDR}") diff --git a/contrib/Fl_Tree/COPYING b/contrib/Fl_Tree/COPYING deleted file mode 100644 index 94ee154c676fe47a849c1f04e3732285b91707fb..0000000000000000000000000000000000000000 --- a/contrib/Fl_Tree/COPYING +++ /dev/null @@ -1,528 +0,0 @@ - Fl_Tree License - May 29, 2005 - -The Fl_Tree library and included programs are provided under the terms -of the GNU Library General Public License (LGPL) with the following -exceptions: - - 1. Modifications to the Fl_Tree configure script, config - header file, and makefiles by themselves to support - a specific platform do not constitute a modified or - derivative work. - - The authors do request that such modifications be - contributed to the Fl_Tree project - send all - contributions to "erco at seriss dot com". - - 2. Widgets that are subclassed from Fl_Tree widgets do not - constitute a derivative work. - - 3. Static linking of applications and widgets to the - Fl_Tree library does not constitute a derivative work - and does not require the author to provide source - code for the application or widget, use the shared - Fl_Tree libraries, or link their applications or - widgets against a user-supplied version of Fl_Tree. - - If you link the application or widget to a modified - version of Fl_Tree, then the changes to Fl_Tree must be - provided under the terms of the LGPL in sections - 1, 2, and 4. - - 4. You do not have to provide a copy of the Fl_Tree license - with programs that are linked to the Fl_Tree library, nor - do you have to identify the Fl_Tree license in your - program or documentation as required by section 6 - of the LGPL. - - However, programs must still identify their use of Fl_Tree. - The following example statement can be included in user - documentation to satisfy this requirement: - - [program/widget] is based in part on the work of - the Fl_Tree project http://seriss.com/people/erco/fltk/Fl_Tree/ - ------------------------------------------------------------------------ - - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - [This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - <one line to give the library's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - <signature of Ty Coon>, 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/contrib/Fl_Tree/FL/Fl_Tree.H b/contrib/Fl_Tree/FL/Fl_Tree.H deleted file mode 100644 index e2e5e304b63b67025828f44142bedba67d854f50..0000000000000000000000000000000000000000 --- a/contrib/Fl_Tree/FL/Fl_Tree.H +++ /dev/null @@ -1,634 +0,0 @@ -#ifndef FL_TREE_H -#define FL_TREE_H - -#include <FL/Fl.H> -#include <FL/Fl_Group.H> -#include <FL/Fl_Scrollbar.H> -#include <FL/fl_draw.H> - -#include <FL/Fl_Tree_Item.H> -#include <FL/Fl_Tree_Prefs.H> - -////////////////////// -// FL/Fl_Tree.H -////////////////////// -// -// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK -// Copyright (C) 2009 by Greg Ercolano. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// USA. -// - -/// -/// \file -/// \brief This file contains the definitions of the Fl_Tree class -/// - -/// \class Fl_Tree -/// -/// \brief Tree widget. -/// -/// \code -/// Fl_Tree // Top level widget -/// |--- Fl_Tree_Item // Items in the tree -/// |--- Fl_Tree_Prefs // Preferences for the tree -/// |--- Fl_Tree_Connector (enum) // Connection modes -/// |--- Fl_Tree_Select (enum) // Selection modes -/// |--- Fl_Tree_Sort (enum) // Sort behavior -/// \endcode -/// -/// An expandable tree widget. -/// -/// Similar to Fl_Browser, Fl_Tree is browser of Fl_Tree_Item's, which can be -/// in a parented hierarchy. Subtrees can be expanded or closed. Items can be -/// added, deleted, inserted, sorted and re-ordered. -/// -/// The tree items may also contain other FLTK widgets, like buttons, input fields, -/// or even "custom" widgets. -/// -/// The simple way to define a tree: -/// \code -/// Fl_Tree tree(X,Y,W,H); -/// tree.begin(); -/// tree.add("Flintstones/Fred"); -/// tree.add("Flintstones/Wilma"); -/// tree.add("Flintstones/Pebbles"); -/// tree.add("Simpsons/Homer"); -/// tree.add("Simpsons/Marge"); -/// tree.add("Simpsons/Bart"); -/// tree.add("Simpsons/Lisa"); -/// tree.end(); -/// \endcode -/// -/// Items can be added with Fl_Tree::add(), -/// removed with Fl_Tree::remove(), -/// inserted with Fl_Tree::insert_above(), -/// selected/deselected with Fl_Tree::select() and Fl_Tree::deselect(). -/// Items can be swapped with Fl_Tree_Item::swap_children(), sorting control via -/// Fl_Tree::sortorder(). -/// -/// The tree can have different selection behaviors controlled by Fl_Tree::selectmode(). -/// -/// FLTK and custom FLTK widgets can be assigned to tree items via Fl_Tree_Item::widget(). -/// -/// Parent nodes can be open/closed with open() and close(), icons can be assigned -/// or redefined with some or all items via -/// Fl_Tree_Item::openicon(), -/// Fl_Tree_Item::closeicon(), -/// Fl_Tree_Item::usericon(). -/// -/// Various default preferences can be manipulated vi Fl_Tree_Prefs, including -/// colors, margins, connection lines. -/// -/// \image html tree-elements.png -/// - -class Fl_Tree : public Fl_Group { - Fl_Tree_Item *_root; // can be null! - Fl_Tree_Item *_item_clicked; - Fl_Tree_Prefs _prefs; // all the tree's settings - Fl_Scrollbar *_vscroll; - -protected: - /// Find the item that was clicked. - /// You probably want to use item_clicked() instead, which is fast. - /// - /// This method walks the entire tree looking for the first item that is - /// under the mouse (ie. at Fl::event_x()/Fl:event_y(). - /// - /// Use this method /only/ if you've subclassed Fl_Tree, and are receiving - /// events before Fl_Tree has been able to process and update item_clicked(). - /// - /// \returns the item clicked, or 0 if no item was under the current event. - /// - const Fl_Tree_Item *find_clicked() const { - if ( ! _root ) return(0); - return(_root->find_clicked()); - } - /// Set the item that was last clicked. - /// Should only be used by subclasses needing to change this value. - /// Normally Fl_Tree manages this value. - /// - void item_clicked(Fl_Tree_Item* val) { - _item_clicked = val; - } - -public: - Fl_Tree(int X, int Y, int W, int H, const char *L=0); - ~Fl_Tree(); - int handle(int e); - void draw(); - - /////////////////////// - // root methods - /////////////////////// - - /// Set the label for the root item. - /// - /// Makes an internally managed copy of 'new_label'. - /// - void root_label(const char *new_label) { - if ( ! _root ) return; - _root->label(new_label); - } - /// Returns the root item. - Fl_Tree_Item* root() { - return(_root); - } - - //////////////////////////////// - // Item creation/removal methods - //////////////////////////////// - Fl_Tree_Item *add(const char *path); - Fl_Tree_Item *insert_above(Fl_Tree_Item *above, const char *name); - - /// Remove the specified 'item' from the tree. - /// If it has children, all those are removed too. - /// \returns 0 if done, -1 if 'item' not found. - /// - int remove(Fl_Tree_Item *item) { - if ( !item ) return(0); - if ( item == _root ) { - clear(); - } else { - Fl_Tree_Item *parent = item->parent(); // find item's parent - if ( ! parent ) return(-1); - parent->remove_child(item); // remove child + children - } - return(0); - } - /// Clear all children from the tree. - /// The tree will be left completely empty. - /// - void clear() { - if ( ! _root ) return; - _root->clear_children(); - delete _root; _root = 0; - } - /// Clear all the children of a particular node in the tree. - void clear_children(Fl_Tree_Item *item) { - if ( item->has_children() ) { - item->clear_children(); - redraw(); // redraw only if there were children to clear - } - } - - //////////////////////// - // Item lookup methods - //////////////////////// - Fl_Tree_Item *find_item(const char *path); - const Fl_Tree_Item *find_item(const char *path) const; - - /// Return the parent for specified 'item'. - /// - /// \returns item's parent, or 0 if none (root). - /// - Fl_Tree_Item *parent(Fl_Tree_Item *item) { - return(item->parent()); - } - /// Return the item that was last clicked. - /// - /// Valid only from within an Fl_Tree::callback(). - /// - /// \returns the item clicked, or 0 if none. - /// - Fl_Tree_Item *item_clicked() { - return(_item_clicked); - } - /// Returns the first item in the tree. - /// - /// Use this to walk the tree in the forward direction, eg: - /// \code - /// for ( Fl_Tree_Item *item = tree->first(); item; item = item->next() ) { - /// printf("Item: %s\n", item->label()); - /// } - /// \endcode - /// - /// \returns first item in tree, or 0 if none (tree empty). - /// - Fl_Tree_Item *first() { - return(_root); // first item always root - } - /// Returns the last item in the tree. - /// - /// Use this to walk the tree in reverse, eg: - /// - /// \code - /// for ( Fl_Tree_Item *item = tree->last(); item; item = item->prev() ) { - /// printf("Item: %s\n", item->label()); - /// } - /// \endcode - /// - /// \returns last item in the tree, or 0 if none (tree empty). - /// - Fl_Tree_Item *last() { - if ( ! _root ) return(0); - Fl_Tree_Item *item = _root; - while ( item->has_children() ) { - item = item->child(item->children()-1); - } - return(item); - } - - ////////////////////////// - // Item open/close methods - ////////////////////////// - - /// Open the specified 'item'. - /// This causes the item's children (if any) to be shown. - /// Handles redrawing if anything was actually changed. - /// - void open(Fl_Tree_Item *item) { - if ( ! item->is_open() ) { - item->open(); - redraw(); - } - } - /// Opens the item specified by a 'menu item' style pathname (eg: "Parent/child/item"). - /// This causes the item's children (if any) to be shown. - /// Handles redrawing if anything was actually changed. - /// - /// \returns - /// - 0 : OK - /// - -1 : item was not found - /// - int open(const char *path) { - Fl_Tree_Item *item = find_item(path); - if ( item ) { - open(item); - return(0); - } - return(-1); - } - /// Closes the 'item'. - /// Handles redrawing if anything was actually changed. - /// - void close(Fl_Tree_Item *item) { - if ( ! item->is_close() ) { - item->close(); - redraw(); - } - } - /// Closes the item specified by 'path', eg: "Parent/child/item". - /// - /// Handles redrawing if anything was actually changed. - /// - /// \returns - /// - 0 -- OK - /// - -1 -- item was not found - /// - int close(const char *path) { - Fl_Tree_Item *item = find_item(path); - if ( item ) { - close(item); - return(0); - } - return(-1); - } - /// See if item is open. - /// - /// Items that are 'open' are themselves not necessarily visible; - /// one of the item's parents might be closed. - /// - /// \returns - /// - 1 : item is open - /// - 0 : item is closed - /// - int is_open(Fl_Tree_Item *item) const { - return(item->is_open()?1:0); - } - /// See if item specified by 'path' (eg: "Parent/child/item") is open. - /// - /// Items that are 'open' are themselves not necessarily visible; - /// one of the item's parents might be closed. - /// - /// \returns - /// - 1 : item is open - /// - 0 : item is closed - /// - -1 : item was not found - /// - int is_open(const char *path) const { - const Fl_Tree_Item *item = find_item(path); - if ( item ) return(item->is_open()?1:0); - return(-1); - } - /// See if item is closed. - /// \returns - /// - 1 : item is open - /// - 0 : item is closed - /// - int is_close(Fl_Tree_Item *item) const { - return(item->is_close()); - } - /// See if item specified by 'path' (eg: "Parent/child/item") is closed. - /// - /// \returns - /// - 1 : item is closed - /// - 0 : item is open - /// - -1 : item was not found - /// - int is_close(const char *path) const { - const Fl_Tree_Item *item = find_item(path); - if ( item ) return(item->is_close()?1:0); - return(-1); - } - - ///////////////////////// - // Item selection methods - ///////////////////////// - - /// Select the specified item. Use 'deselect()' to de-select it. - /// Handles redrawing if anything was actually changed. - /// - void select(Fl_Tree_Item *item) { - if ( ! item->is_selected() ) { - item->select(); - redraw(); - } - } - /// Select an item specified by 'path' (eg: "Parent/child/item"). - /// Handles redrawing if anything was actually changed. - /// - /// \returns - /// - 0 : OK - /// - -1 : item was not found - /// - int select(const char *path) { - Fl_Tree_Item *item = find_item(path); - if ( item ) { - select(item); - return(0); - } - return(-1); - } - /// Toggle item's select state. - /// Handles redrawing. - /// - void select_toggle(Fl_Tree_Item *item) { - item->select_toggle(); - redraw(); - } - /// De-select the specified item. - /// Handles redrawing if anything was actually changed. - /// - void deselect(Fl_Tree_Item *item) { - if ( item->is_selected() ) { - item->deselect(); - redraw(); - } - } - /// De-select an item specified by 'path' (eg: "Parent/child/item"). - /// Handles redrawing if anything was actually changed. - /// - /// \returns - /// - 0 : OK - /// - -1 : item was not found - /// - int deselect(const char *path) { - Fl_Tree_Item *item = find_item(path); - if ( item ) { - deselect(item); - return(0); - } - return(-1); - } - - int deselect_all(Fl_Tree_Item *item=0); - int select_only(Fl_Tree_Item *selitem); - - /// See if the specified item is selected. - /// \return - /// - 1 : item selected - /// - 0 : item deselected - /// - int is_selected(Fl_Tree_Item *item) const { - return(item->is_selected()?1:0); - } - /// See if item specified by 'path' (eg: "Parent/child/item") is selected. - /// - /// \returns - /// - 1 : item selected - /// - 0 : item deselected - /// - -1 : item was not found - /// - int is_selected(const char *path) { - Fl_Tree_Item *item = find_item(path); - if ( item ) return(is_selected(item)); - return(-1); - } - /// Print the tree as 'ascii art' to stdout. - /// Used mainly for debugging. - /// - void show_self() { - if ( ! _root ) return; - _root->show_self(); - } - - ///////////////////////////////// - // Item attribute related methods - ///////////////////////////////// - - /// Get the default label fontsize used for creating new items. - int labelsize() const { - return(_prefs.labelsize()); - } - /// Set the default label font size used for creating new items. - /// To change the font size on a per-item basis, use Fl_Tree_Item::labelsize(int) - /// - void labelsize(int val) { - _prefs.labelsize(val); - } - - /// Get the default font face used for item's labels when new items are created. - /// - /// Don't use this if you want to change an existing label() size; use - /// item->labelfont() instead. - /// - int labelfont() const { - return(_prefs.labelfont()); - } - /// Set the default font face used for item's labels when new items are created. - /// - /// Don't use this if you want to change an existing label() size; use - /// item->labelfont(int) instead. - /// - void labelfont(int val) { - _prefs.labelfont(val); - } - /// Get the amount of white space (in pixels) that should appear - /// between the widget's left border and the tree's contents. - /// - int marginleft() const { - return(_prefs.marginleft()); - } - /// Set the amount of white space (in pixels) that should appear - /// between the widget's left border and the left side of the tree's contents. - /// - void marginleft(int val) { - _prefs.marginleft(val); - redraw(); - } - /// Get the amount of white space (in pixels) that should appear - /// between the widget's top border and the top of the tree's contents. - /// - int margintop() const { - return(_prefs.margintop()); - } - /// Sets the amount of white space (in pixels) that should appear - /// between the widget's top border and the top of the tree's contents. - /// - void margintop(int val) { - _prefs.margintop(val); - redraw(); - } - /// Gets the width of the horizontal connection lines (in pixels) - /// that appear to the left of each tree item's label. - /// - int connectorwidth() const { - return(_prefs.connectorwidth()); - } - /// Sets the width of the horizontal connection lines (in pixels) - /// that appear to the left of each tree item's label. - /// - void connectorwidth(int val) { - _prefs.connectorwidth(val); - redraw(); - } - /// Returns the Fl_Pixmap being used as the default user icon for newly created items. - /// Returns zero if no icon has been set, which is the default. - /// - Fl_Pixmap *usericon() const { - return(_prefs.usericon()); - } - /// Sets the Fl_Pixmap to be used as the default user icon for all - /// newly created items. - /// - /// If you want to specify user icons on a per-item basis, - /// use Fl_Tree_Item::usericon() instead. - /// - /// \param[in] val -- The new pixmap to be used, or - /// zero to disable user icons. - /// - void usericon(Fl_Pixmap *val) { - _prefs.usericon(val); - redraw(); - } - /// Returns the icon to be used as the 'open' icon. - /// If none was set, the internal default is returned, - /// a simple '[+]' icon. - /// - Fl_Pixmap *openicon() const { - return(_prefs.openicon()); - } - /// Sets the icon to be used as the 'open' icon. - /// This overrides the built in default '[+]' icon. - /// - /// \param[in] val -- The new pixmap, or zero to use the default [+] icon. - /// - void openicon(Fl_Pixmap *val) { - _prefs.openicon(val); - redraw(); - } - /// Returns the icon to be used as the 'close' icon. - /// If none was set, the internal default is returned, - /// a simple '[-]' icon. - /// - Fl_Pixmap *closeicon() const { - return(_prefs.closeicon()); - } - /// Sets the icon to be used as the 'close' icon. - /// This overrides the built in default '[-]' icon. - /// - /// \param[in] val -- The new pixmap, or zero to use the default [-] icon. - /// - void closeicon(Fl_Pixmap *val) { - _prefs.closeicon(val); - redraw(); - } - /// Returns 1 if the collapse icon is enabled, 0 if not. - int showcollapse() const { - return(_prefs.showcollapse()); - } - /// Set if we should show the collapse icon or not. - /// If collapse icons are disabled, the user will not be able - /// to interactively collapse items in the tree, unless the application - /// provides some other means via open() and close(). - /// - /// \param[in] val 1: shows collapse icons (default),\n - /// 0: hides collapse icons. - /// - void showcollapse(int val) { - _prefs.showcollapse(val); - redraw(); - } - /// Returns 1 if the root item is to be shown, or 0 if not. - int showroot() const { - return(_prefs.showroot()); - } - /// Set if the root item should be shown or not. - /// \param[in] val 1 -- show the root item (default)\n - /// 0 -- hide the root item. - /// - void showroot(int val) { - _prefs.showroot(val); - redraw(); - } - /// Returns the line drawing style for inter-connecting items. - Fl_Tree_Connector connectorstyle() const { - return(_prefs.connectorstyle()); - } - /// Sets the line drawing style for inter-connecting items. - void connectorstyle(Fl_Tree_Connector val) { - _prefs.connectorstyle(val); - redraw(); - } - /// Set the default sort order used when items are added to the tree. - /// See Fl_Tree_Sort for possible values. - /// - Fl_Tree_Sort sortorder() const { - return(_prefs.sortorder()); - } - /// Gets the sort order used to add items to the tree. - void sortorder(Fl_Tree_Sort val) { - _prefs.sortorder(val); - // no redraw().. only affects new add()itions - } - /// Sets the style of box used to draw selected items. - /// This is an fltk Fl_Boxtype. - /// The default is influenced by FLTK's current Fl::scheme() - /// - Fl_Boxtype selectbox() const { - return(_prefs.selectbox()); - } - /// Gets the style of box used to draw selected items. - /// This is an fltk Fl_Boxtype. - /// The default is influenced by FLTK's current Fl::scheme() - /// - void selectbox(Fl_Boxtype val) { - _prefs.selectbox(val); - redraw(); - } - /// Gets the tree's current selection mode. - Fl_Tree_Select selectmode() const { - return(_prefs.selectmode()); - } - /// Sets the tree's selection mode. - void selectmode(Fl_Tree_Select val) { - _prefs.selectmode(val); - } -}; - -#endif /*FL_TREE_H*/ diff --git a/contrib/Fl_Tree/FL/Fl_Tree_Item.H b/contrib/Fl_Tree/FL/Fl_Tree_Item.H deleted file mode 100644 index b2d67ba76b3900aef9805003ea9411c9bc5aa4dc..0000000000000000000000000000000000000000 --- a/contrib/Fl_Tree/FL/Fl_Tree_Item.H +++ /dev/null @@ -1,301 +0,0 @@ -#ifndef FL_TREE_ITEM_H -#define FL_TREE_ITEM_H - -#include <FL/Fl.H> -#include <FL/Fl_Widget.H> -#include <FL/Fl_Pixmap.H> -#include <FL/fl_draw.H> - -#include <FL/Fl_Tree_Item_Array.H> -#include <FL/Fl_Tree_Prefs.H> - -////////////////////// -// FL/Fl_Tree_Item.H -////////////////////// -// -// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK -// Copyright (C) 2009 by Greg Ercolano. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// USA. -// - -/// -/// \file -/// \brief This file contains the definitions for Fl_Tree_Item -/// - -/// \brief Tree item -/// -/// This class is a single tree item, and manages all of the item's attributes. -/// Fl_Tree_Item is used by Fl_Tree, which is comprised of many instances of Fl_Tree_Item. -/// -/// Fl_Tree_Item is hierarchical; it dynamically manages an Fl_Tree_Item_Array of children -/// that are themselves instances of Fl_Tree_Item. Each item can have zero or more children. -/// When an item has children, close() and open() can be used to hide or show them. -/// -/// Items have their own attributes; font size, face, color. -/// Items maintain their own hierarchy of children. -/// -/// When you make changes to items, you'll need to tell the tree to redraw() -/// for the changes to show up. -/// -/// -class Fl_Tree_Item { - const char *_label; // label (memory managed) - int _labelfont; // label's font face - int _labelsize; // label's font size - Fl_Color _labelfgcolor; // label's fg color - Fl_Color _labelbgcolor; // label's bg color - char _open; // item is open? - char _visible; // item is visible? - char _active; // item activated? - char _selected; // item selected? - int _xywh[4]; // xywh of this widget (if visible) - int _collapse_xywh[4]; // xywh of collapse icon (if any) - int _label_xywh[4]; // xywh of label - Fl_Widget *_widget; // item's label widget (optional) - Fl_Pixmap *_usericon; // item's user-specific icon (optional) - void *_userdata; // item's user-specific data (optional) GMSH - Fl_Tree_Item_Array _children; // array of child items - Fl_Tree_Item *_parent; // parent item (=0 if root) -protected: - void show_widgets(); - void hide_widgets(); - void draw_vertical_connector(int x, int y1, int y2, const Fl_Tree_Prefs &prefs); - void draw_horizontal_connector(int x1, int x2, int y, const Fl_Tree_Prefs &prefs); -public: - Fl_Tree_Item(const Fl_Tree_Prefs &prefs); // CTOR - ~Fl_Tree_Item(); // DTOR - Fl_Tree_Item(const Fl_Tree_Item *o); // COPY CTOR - void draw(int X, int &Y, int W, Fl_Widget *tree, const Fl_Tree_Prefs &prefs, int lastchild=1); - void show_self(const char *indent = "") const; - void label(const char *val); - const char *label() const; - - /// Set item's label font face. - void labelfont(int val) { - _labelfont = val; - } - /// Get item's label font face. - int labelfont() const { - return(_labelfont); - } - /// Set item's label font size. - void labelsize(int val) { - _labelsize = val; - } - /// Get item's label font size. - int labelsize() const { - return(_labelsize); - } - /// Set item's label foreground text color. - void labelfgcolor(Fl_Color val) { - _labelfgcolor = val; - } - /// Set item's label text color. - void labelcolor(Fl_Color val) { - _labelfgcolor = val; - } - /// Return item's label text color. - Fl_Color labelcolor() const { - return(_labelfgcolor); - } - /// Return item's label foreground text color. - Fl_Color labelfgcolor() const { - return(_labelfgcolor); - } - /// Set item's label background color. - void labelbgcolor(Fl_Color val) { - _labelbgcolor = val; - } - /// Return item's background text color. - Fl_Color labelbgcolor() const { - return(_labelbgcolor); - } - /// Assign an FLTK widget to this item. - void widget(Fl_Widget *val) { - _widget = val; - } - /// Return FLTK widget assigned to this item. - Fl_Widget *widget() const { - return(_widget); - } - /// Return the number of children this item has. - int children() const { - return(_children.total()); - } - /// Return the child item for the given 'index'. - Fl_Tree_Item *child(int index) { - return(_children[index]); - } - /// Return the const child item for the given 'index'. - const Fl_Tree_Item *child(int t) const; - /// See if this item has children. - int has_children() const { - return(children()); - } - int find_child(const char *name); - int find_child(Fl_Tree_Item *item); - int remove_child(Fl_Tree_Item *item); - int remove_child(const char *new_label); - void clear_children(); - void swap_children(int ax, int bx); - int swap_children(Fl_Tree_Item *a, Fl_Tree_Item *b); - const Fl_Tree_Item *find_item(char **arr) const; - Fl_Tree_Item *find_item(char **arr); - ////////////////// - // Adding items - ////////////////// - Fl_Tree_Item *add(const Fl_Tree_Prefs &prefs, const char *new_label); - Fl_Tree_Item *add(const Fl_Tree_Prefs &prefs, char **arr); - Fl_Tree_Item *insert(const Fl_Tree_Prefs &prefs, const char *new_label, int pos=0); - Fl_Tree_Item *insert_above(const Fl_Tree_Prefs &prefs, const char *new_label); - int depth() const; - Fl_Tree_Item *prev(); - Fl_Tree_Item *next(); - - /// Return the parent for this item. - Fl_Tree_Item *parent() { - return(_parent); - } - /// Return the const parent for this item. - const Fl_Tree_Item *parent() const { - return(_parent); - } - /// Set the parent for this item. - /// Should only be used by Fl_Tree's internals. - /// - void parent(Fl_Tree_Item *val) { - _parent = val; - } - ////////////////// - // State - ////////////////// - void open(); - void close(); - /// See if the item is 'open'. - int is_open() const { - return(_open?1:0); - } - /// See if the item is 'closed'. - int is_close() const { - return(_open?0:1); - } - /// Toggle the item's open/closed state. - void open_toggle() { - _open?close():open(); - } - /// Change the item's selection state to the optionally specified 'val'. - /// If 'val' is not specified, the item will be selected. - /// - void select(int val=1) { - _selected = val; - } - /// Toggle the item's selection state. - void select_toggle() { - if ( is_selected() ) { - deselect(); // deselect if selected - } else { - select(); // select if deselected - } - } - /// Disable the item's selection state. - void deselect() { - _selected = 0; - } - /// Deselect self and all children - /// Returns count of how many items were in the 'selected' state, - /// ie. how many items were "changed". - /// - int deselect_all() { - int count = 0; - if ( is_selected() ) { - deselect(); - ++count; - } - for ( int t=0; t<children(); t++ ) { - count += child(t)->deselect_all(); - } - return(count); - } - /// See if the item is selected. - char is_selected() const { - return(_selected); - } - /// Change the item's activation state to the optionally specified 'val'. - /// - /// When deactivated, the item will be 'grayed out'; the callback() - /// won't be invoked if the user clicks on the label. If the item - /// has a widget() associated with the item, its activation state - /// will be changed as well. - /// - /// If 'val' is not specified, the item will be activated. - /// - void activate(int val=1) { - _active = val; - if ( _widget && val != _widget->active() ) { - if ( val ) { - _widget->activate(); - } else { - _widget->deactivate(); - } - _widget->redraw(); - } - } - /// Deactivate the item; the callback() won't be invoked when clicked. - /// Same as activate(0) - /// - void deactivate() { - activate(0); - } - /// See if the item is activated. - char is_activated() const { - return(_active); - } - /// See if the item is activated. - char is_active() const { - return(_active); - } - /// Set the user icon's pixmap. '0' will disable. - void usericon(Fl_Pixmap *val) { - _usericon = val; - } - /// Get the user icon. Returns '0' if disabled. - Fl_Pixmap *usericon() const { - return(_usericon); - } - /// Set the user data. - void user_data(void *val) { - _userdata = val; - } - /// Get the user data. - void *user_data() const { - return(_userdata); - } - ////////////////// - // Events - ////////////////// - const Fl_Tree_Item *find_clicked() const; - Fl_Tree_Item *find_clicked(); - int event_on_collapse_icon(const Fl_Tree_Prefs &prefs) const; - int event_on_label(const Fl_Tree_Prefs &prefs) const; - /// Is this item the root of the tree? - int is_root() const { - return(_parent==0?1:0); - } -}; - -#endif /*FL_TREE_ITEM_H*/ diff --git a/contrib/Fl_Tree/FL/Fl_Tree_Item_Array.H b/contrib/Fl_Tree/FL/Fl_Tree_Item_Array.H deleted file mode 100644 index b7f455ac865396cdc8c40373f5dcbf2a7a747cfa..0000000000000000000000000000000000000000 --- a/contrib/Fl_Tree/FL/Fl_Tree_Item_Array.H +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef _FL_TREE_ITEM_ARRAY_H -#define _FL_TREE_ITEM_ARRAY_H - -class Fl_Tree_Item; // forward decl must *precede* first doxygen comment block - // or doxygen will not document our class.. - -////////////////////// -// FL/Fl_Tree_Item_Array.H -////////////////////// -// -// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK -// Copyright (C) 2009 by Greg Ercolano. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// USA. -// - -/// -/// \file -/// \brief This file defines a class that manages an array of Fl_Tree_Item pointers. -/// - -/// \brief Manages an array of Fl_Tree_Item pointers. -/// -/// Because FLTK 1.x.x. has mandated that templates and STL not be used, -/// we use this class to dynamically manage the arrays. -/// -/// None of the methods do range checking on index values; the caller -/// must be sure that index values are within the range 0<index<total() -/// (unless otherwise noted). -/// - -class Fl_Tree_Item_Array { - Fl_Tree_Item **_items; // items array - int _total; // #items in array - int _size; // #items *allocated* for array - int _chunksize; // #items to enlarge mem allocation - void enlarge(int count); -public: - Fl_Tree_Item_Array(int new_chunksize = 10); // CTOR - ~Fl_Tree_Item_Array(); // DTOR - Fl_Tree_Item_Array(const Fl_Tree_Item_Array *o); // COPY CTOR - /// Return the item and index \p i. - Fl_Tree_Item *operator[](int i) { - return(_items[i]); - } - /// Const version of operator[](int i) - const Fl_Tree_Item *operator[](int i) const { - return(_items[i]); - } - /// Return the total items in the array, or 0 if empty. - int total() const { - return(_total); - } - /// Swap the two items at index positions \p ax and \p bx. - void swap(int ax, int bx) { - Fl_Tree_Item *asave = _items[ax]; - _items[ax] = _items[bx]; - _items[bx] = asave; - } - void clear(); - void add(Fl_Tree_Item *val); - void insert(int pos, Fl_Tree_Item *new_item); - void remove(int index); - int remove(Fl_Tree_Item *item); -}; - -#endif /*_FL_TREE_ITEM_ARRAY_H*/ diff --git a/contrib/Fl_Tree/FL/Fl_Tree_Prefs.H b/contrib/Fl_Tree/FL/Fl_Tree_Prefs.H deleted file mode 100644 index c9ce6e1dc62331db0b79caae1cd075b2737e0cb5..0000000000000000000000000000000000000000 --- a/contrib/Fl_Tree/FL/Fl_Tree_Prefs.H +++ /dev/null @@ -1,340 +0,0 @@ -#ifndef FL_TREE_PREFS_H -#define FL_TREE_PREFS_H - -////////////////////// -// FL/Fl_Tree_Prefs.H -////////////////////// -// -// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK -// Copyright (C) 2009 by Greg Ercolano. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// USA. -// - -/// -/// \file -/// \brief This file contains the definitions for Fl_Tree's preferences. -/// -/// \code -/// Fl_Tree_Prefs -/// : -/// .....:....... -/// : : -/// Fl_Tree : -/// |_____ Fl_Tree_Item -/// -/// \endcode -/// - -/// \class Fl_Tree_Prefs -/// \brief Tree widget's preferences. - -/// \enum Fl_Tree_Sort -/// Sort order options for items added to the tree -/// -enum Fl_Tree_Sort { - FL_TREE_SORT_NONE=0, ///< No sorting; items are added in the order defined (default). - FL_TREE_SORT_ASCENDING=1, ///< Add items in ascending sort order. - FL_TREE_SORT_DESCENDING=2 ///< Add items in descending sort order. -}; - -/// \enum Fl_Tree_Connector -/// Defines the style of connection lines between items. -/// -enum Fl_Tree_Connector { - FL_TREE_CONNECTOR_NONE=0, ///< Use no lines connecting items - FL_TREE_CONNECTOR_DOTTED=1, ///< Use dotted lines connecting items (default) - FL_TREE_CONNECTOR_SOLID=2 ///< Use solid lines connecting items -}; - -/// \enum Fl_Tree_Select -/// Tree selection style. -/// -enum Fl_Tree_Select { - FL_TREE_SELECT_NONE=0, ///< Nothing selected when items are clicked - FL_TREE_SELECT_SINGLE, ///< Single item selected when item is clicked (default) - FL_TREE_SELECT_MULTI ///< Multiple items can be selected by clicking with - ///< SHIFT or CTRL or mouse drags. -}; - -/// \class Fl_Tree_Prefs -/// -/// \brief Fl_Tree's Preferences class. -/// -/// This class manages the Fl_Tree's defaults. -/// You should probably be using the methods in Fl_Tree -/// instead of trying to accessing tree's preferences settings directly. -/// -class Fl_Tree_Prefs { - int _labelfont; // label's font face - int _labelsize; // label's font size - int _margintop; // -- - int _marginleft; // |- tree's margins - //int _marginright; // | - //int _marginbottom; // -- - int _usericonmarginleft; // space to left of user icon (if any) - int _labelmarginleft; // space to left of label - int _connectorwidth; // connector width (right of open/close icon) - int _linespacing; // vertical space between lines - // Colors - Fl_Color _fgcolor; // label's foreground color - Fl_Color _bgcolor; // background color - Fl_Color _selectcolor; // selection color - Fl_Color _inactivecolor; // inactive color - Fl_Color _connectorcolor; // connector dotted line color - Fl_Tree_Connector _connectorstyle; // connector line style - Fl_Pixmap *_openpixmap; // the 'open' icon [+] - Fl_Pixmap *_closepixmap; // the 'close' icon [-] - Fl_Pixmap *_userpixmap; // user's own icon - char _showcollapse; // 1=show collapse icons, 0=don't - char _showroot; // show the root item as part of the tree - Fl_Tree_Sort _sortorder; // none, ascening, descending, etc. - Fl_Boxtype _selectbox; // selection box type - Fl_Tree_Select _selectmode; // selection mode -public: - Fl_Tree_Prefs(); - - //////////////////////////// - // Labels - //////////////////////////// - /// Return the label's font. - inline int labelfont() const { - return(_labelfont); - } - /// Set the label's font to \p val. - inline void labelfont(int val) { - _labelfont = val; - } - /// Return the label's size in pixels. - inline int labelsize() const { - return(_labelsize); - } - /// Set the label's size in pixels to \p val. - inline void labelsize(int val) { - _labelsize = val; - } - - //////////////////////////// - // Margins - //////////////////////////// - /// Get the left margin's value in pixels - inline int marginleft() const { - return(_marginleft); - } - /// Set the left margin's value in pixels - inline void marginleft(int val) { - _marginleft = val; - } - /// Get the top margin's value in pixels - inline int margintop() const { - return(_margintop); - } - /// Set the top margin's value in pixels - inline void margintop(int val) { - _margintop = val; - } - -/****** NOT IMPLEMENTED - inline int marginright() const { - return(_marginright); - } - inline void marginright(int val) { - _marginright = val; - } - inline int marginbottom() const { - return(_marginbottom); - } - inline void marginbottom(int val) { - _marginbottom = val; - } -*******/ - - /// Get the user icon's left margin value in pixels - inline int usericonmarginleft() const { - return(_usericonmarginleft); - } - /// Set the user icon's left margin value in pixels - inline void usericonmarginleft(int val) { - _usericonmarginleft = val; - } - /// Get the label's left margin value in pixels - inline int labelmarginleft() const { - return(_labelmarginleft); - } - /// Set the label's left margin value in pixels - inline void labelmarginleft(int val) { - _labelmarginleft = val; - } - /// Get the line spacing value in pixels - inline int linespacing() const { - return(_linespacing); - } - /// Set the line spacing value in pixels - inline void linespacing(int val) { - _linespacing = val; - } - - //////////////////////////// - // Colors and Styles - //////////////////////////// - /// Get the default label foreground color - inline Fl_Color fgcolor() const { - return(_fgcolor); - } - /// Set the default label foreground color - inline void fgcolor(Fl_Color val) { - _fgcolor = val; - } - /// Get the default label background color - inline Fl_Color bgcolor() const { - return(_bgcolor); - } - /// Set the default label background color - inline void bgcolor(Fl_Color val) { - _bgcolor = val; - } - /// Get the default selection color - inline Fl_Color selectcolor() const { - return(_selectcolor); - } - /// Set the default selection color - inline void selectcolor(Fl_Color val) { - _selectcolor = val; - } - /// Get the default inactive color - inline Fl_Color inactivecolor() const { - return(_inactivecolor); - } - /// Set the default inactive color - inline void inactivecolor(Fl_Color val) { - _inactivecolor = val; - } - /// Get the connector color; the color used for tree connection lines - inline Fl_Color connectorcolor() const { - return(_connectorcolor); - } - /// Set the connector color; the color used for tree connection lines - inline void connectorcolor(Fl_Color val) { - _connectorcolor = val; - } - /// Get the connector style - inline Fl_Tree_Connector connectorstyle() const { - return(_connectorstyle); - } - /// Set the connector style - inline void connectorstyle(Fl_Tree_Connector val) { - _connectorstyle = val; - } - /// Get the tree connection line's width - inline int connectorwidth() const { - return(_connectorwidth); - } - /// Set the tree connection line's width - inline void connectorwidth(int val) { - _connectorwidth = val; - } - - //////////////////////////// - // Icons - //////////////////////////// - /// Get the current default 'open' icon. - /// Returns the Fl_Pixmap* of the icon, or 0 if none. - /// - inline Fl_Pixmap *openicon() const { - return(_openpixmap); - } - void openicon(Fl_Pixmap *val); - /// Gets the default 'close' icon - /// Returns the Fl_Pixmap* of the icon, or 0 if none. - /// - inline Fl_Pixmap *closeicon() const { - return(_closepixmap); - } - void closeicon(Fl_Pixmap *val); - /// Gets the default 'user icon' (default is 0) - inline Fl_Pixmap *usericon() const { - return(_userpixmap); - } - /// Sets the default 'user icon' - /// Returns the Fl_Pixmap* of the icon, or 0 if none (default). - /// - inline void usericon(Fl_Pixmap *val) { - _userpixmap = val; - } - - //////////////////////////// - // Options - //////////////////////////// - /// Returns 1 if the collapse icon is enabled, 0 if not. - inline char showcollapse() const { - return(_showcollapse); - } - /// Set if we should show the collapse icon or not. - /// If collapse icons are disabled, the user will not be able - /// to interactively collapse items in the tree, unless the application - /// provides some other means via open() and close(). - /// - /// \param[in] val 1: shows collapse icons (default),\n - /// 0: hides collapse icons. - /// - inline void showcollapse(int val) { - _showcollapse = val; - } - /// Get the default sort order value - inline Fl_Tree_Sort sortorder() const { - return(_sortorder); - } - /// Set the default sort order value. - /// Defines the order new items appear when add()ed to the tree. - /// See Fl_Tree_Sort for possible values. - /// - inline void sortorder(Fl_Tree_Sort val) { - _sortorder = val; - } - /// Get the default selection box's box drawing style as an Fl_Boxtype. - inline Fl_Boxtype selectbox() const { - return(_selectbox); - } - /// Set the default selection box's box drawing style to \p val. - inline void selectbox(Fl_Boxtype val) { - _selectbox = val; - } - /// Returns 1 if the root item is to be shown, or 0 if not. - inline int showroot() const { - return(int(_showroot)); - } - /// Set if the root item should be shown or not. - /// \param[in] val 1 -- show the root item (default)\n - /// 0 -- hide the root item. - /// - inline void showroot(int val) { - _showroot = char(val); - } - /// Get the selection mode used for the tree - inline Fl_Tree_Select selectmode() const { - return(_selectmode); - } - /// Set the selection mode used for the tree to \p val. - /// This affects how items in the tree are selected - /// when clicked on and dragged over by the mouse. - /// See Fl_Tree_Select for possible values. - /// - inline void selectmode(Fl_Tree_Select val) { - _selectmode = val; - } -}; - -#endif /*FL_TREE_PREFS_H*/ diff --git a/contrib/Fl_Tree/Fl_Tree.cxx b/contrib/Fl_Tree/Fl_Tree.cxx deleted file mode 100644 index 7ca569568a8dc6eee443dd1a06a31fd0c70cbe6f..0000000000000000000000000000000000000000 --- a/contrib/Fl_Tree/Fl_Tree.cxx +++ /dev/null @@ -1,407 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <FL/Fl_Tree.H> - -#define SCROLL_W 15 - -////////////////////// -// Fl_Tree.cxx -////////////////////// -// -// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK -// Copyright (C) 2009 by Greg Ercolano. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// USA. -// - -/// \mainpage Fl_Tree Widget -/// -/// \image html tree-simple-screenshot.png -/// -/// \code -/// Fl_Tree // Top level widget -/// |--- Fl_Tree_Item // Items in the tree -/// |--- Fl_Tree_Prefs // Preferences for the tree -/// |--- Fl_Tree_Connector (enum) // Connection modes -/// |--- Fl_Tree_Select (enum) // Selection modes -/// |--- Fl_Tree_Sort (enum) // Sort behavior -/// -/// \endcode -/// -/// \b Overview -/// <P> -/// This is a hierarchical 'tree' browser widget that presents its data -/// in a hierarchy. Nodes can optionally be open/closed, and items can -/// be individually created, deleted, sorted, and attributes customized -/// for different fonts and colors. -/// -/// The simple way to define a tree: -/// \code -/// Fl_Tree tree(X,Y,W,H); -/// tree.begin(); -/// tree.add("Flintstones/Fred"); -/// tree.add("Flintstones/Wilma"); -/// tree.add("Flintstones/Pebbles"); -/// tree.add("Simpsons/Homer"); -/// tree.add("Simpsons/Marge"); -/// tree.add("Simpsons/Bart"); -/// tree.add("Simpsons/Lisa"); -/// tree.end(); -/// \endcode -/// -/// Items can also be FLTK widgets, instead of just simple labels (default). -/// -/// Fl_Tree derives from FLTK's Fl_Group, so that if FLTK widgets are added -/// to the tree, they become children of the group. -/// -/// Each item in the tree is an Fl_Tree_Item, which has customizable -/// values for setting the font, color, and other attributes on a per-item -/// basis. -/// -/// Each tree contains an instance of the Fl_Tree_Prefs class, which handles -/// global preferences for the tree, and the default values used for newly -/// created items in the tree. -/// -/// By default, when items are added to the tree, they're added in the order created. -/// Sorting can be specified with the Fl_Tree::sortorder() method. -/// -/// \image html tree-elements.png -/// - -// INTERNAL: scroller callback -static void scroll_cb(Fl_Widget*,void *data) { - ((Fl_Tree*)data)->redraw(); -} - -// INTERNAL: Parse elements from path -// Path="/aa/bb" -// Return: arr[0]="aa", arr[1]="bb", arr[2]=0 -// Caller must: free(arr[0]); free(arr); -// -static char **parse_path(const char *path) { - while ( *path == '/' ) path++; // skip leading '/' - // First pass: identify, null terminate, and count separators - int seps = 1; // separator count (1: first item) - int arrsize = 1; // array size (1: first item) - char *save = strdup(path); // make copy we can modify - char *s = save; - while ( ( s = strchr(s, '/') ) ) { - while ( *s == '/' ) { *s++ = 0; seps++; } - if ( *s ) { arrsize++; } - } - arrsize++; // (room for terminating NULL) - // Second pass: create array, save nonblank elements - char **arr = (char**)malloc(sizeof(char*) * arrsize); - int t = 0; - s = save; - while ( seps-- > 0 ) { - if ( *s ) { arr[t++] = s; } // skips empty fields, eg. '//' - s += (strlen(s) + 1); - } - arr[t] = 0; - return(arr); -} - -// INTERNAL: Recursively descend tree hierarchy, accumulating total child count -static int find_total_children(Fl_Tree_Item *item, int count=0) { - count++; - for ( int t=0; t<item->children(); t++ ) { - count = find_total_children(item->child(t), count); - } - return(count); -} - -/// Constructor. -Fl_Tree::Fl_Tree(int X, int Y, int W, int H, const char *L) : Fl_Group(X,Y,W,H,L) { - _root = new Fl_Tree_Item(_prefs); - _root->parent(0); // we are root of tree - _root->label("ROOT"); - _item_clicked = 0; - box(FL_DOWN_BOX); - color(FL_WHITE); - when(FL_WHEN_CHANGED); - _vscroll = new Fl_Scrollbar(0,0,0,0); // will be resized by draw() - _vscroll->hide(); - _vscroll->type(FL_VERTICAL); - _vscroll->step(1); - _vscroll->callback(scroll_cb, (void*)this); - end(); -} - -/// Destructor. -Fl_Tree::~Fl_Tree() { - if ( _root ) { delete _root; _root = 0; } -} - -/// Adds a new item, given a 'menu style' path, eg: "/Parent/Child/item". -/// Any parent nodes that don't already exist are created automatically. -/// Adds the item based on the value of sortorder(). -/// \returns the child item created, or 0 on error. -/// -Fl_Tree_Item* Fl_Tree::add(const char *path) { - if ( ! _root ) { // Create root if none - _root = new Fl_Tree_Item(_prefs); - _root->parent(0); - _root->label("ROOT"); - } - char **arr = parse_path(path); - Fl_Tree_Item *item = _root->add(_prefs, arr); - free((void*)arr[0]); - free((void*)arr); - return(item); -} - -/// Inserts a new item above the specified Fl_Tree_Item, with the label set to 'name'. -/// \returns the item that was added, or 0 if 'above' could not be found. -/// -Fl_Tree_Item* Fl_Tree::insert_above(Fl_Tree_Item *above, const char *name) { - return(above->insert_above(_prefs, name)); -} - -/// Find the item, given a menu style path, eg: "/Parent/Child/item". -/// -/// There is both a const and non-const version of this method. -/// Const version allows pure const methods to use this method -/// to do lookups without causing compiler errors. -/// \returns the item, or 0 if not found. -/// -Fl_Tree_Item *Fl_Tree::find_item(const char *path) { - if ( ! _root ) return(0); - char **arr = parse_path(path); - Fl_Tree_Item *item = _root->find_item(arr); - free((void*)arr[0]); - free((void*)arr); - return(item); -} - -/// A const version of Fl_Tree::find_item(const char *path) -const Fl_Tree_Item *Fl_Tree::find_item(const char *path) const { - if ( ! _root ) return(0); - char **arr = parse_path(path); - const Fl_Tree_Item *item = _root->find_item(arr); - free((void*)arr[0]); - free((void*)arr); - return(item); -} - -/// Standard FLTK draw() method, handles draws the tree widget. -void Fl_Tree::draw() { - // Let group draw box+label but *NOT* children. - // *We* handle drawing children ourselves by calling each item's draw() - // - Fl_Group::draw_box(); - Fl_Group::draw_label(); - if ( ! _root ) return; - int cx = x() + Fl::box_dx(box()); - int cy = y() + Fl::box_dy(box()); - int cw = w() - Fl::box_dw(box()); - int ch = h() - Fl::box_dh(box()); - // These valued changed during drawing - // 'Y' will be the lowest point on the tree - int X = cx + _prefs.marginleft(); - int Y = cy + _prefs.margintop() - (_vscroll->visible() ? _vscroll->value() : 0); - int W = cw - _prefs.marginleft(); // - _prefs.marginright(); - int Ysave = Y; - fl_push_clip(cx,cy,cw,ch); - { - fl_font(_prefs.labelfont(), _prefs.labelsize()); - _root->draw(X, Y, W, this, _prefs); - } - fl_pop_clip(); - // Should we show vertical scrollbar? - int ydiff = (Y+_prefs.margintop())-Ysave; // ydiff=size of tree - int ytoofar = (cy+ch) - Y; // ytoofar -- scrolled beyond bottom (eg. stow) - - //printf("ydiff=%d ch=%d Ysave=%d ytoofar=%d value=%d\n", - //int(ydiff),int(ch),int(Ysave),int(ytoofar), int(_vscroll->value())); - - if ( ytoofar > 0 ) ydiff += ytoofar; - if ( Ysave<cy || ydiff > ch || int(_vscroll->value()) > 1 ) { - _vscroll->visible(); - int sx = x()+w()-Fl::box_dx(box())-SCROLL_W; - int sy = y()+Fl::box_dy(box()); - int sw = SCROLL_W; - int sh = h()-Fl::box_dh(box()); - _vscroll->show(); - _vscroll->range(0.0,ydiff-ch); - _vscroll->resize(sx,sy,sw,sh); - _vscroll->slider_size(float(ch)/float(ydiff)); - } else { - _vscroll->Fl_Slider::value(0); - _vscroll->hide(); - } - fl_push_clip(cx,cy,cw,ch); - Fl_Group::draw_children(); - fl_pop_clip(); -} - -/// Standard FLTK event handler for this widget. -int Fl_Tree::handle(int e) { - static Fl_Tree_Item *lastselect = 0; - int changed = 0; - int ret = Fl_Group::handle(e); - if ( ! _root ) return(ret); - switch ( e ) { - case FL_PUSH: { - lastselect = 0; - item_clicked(0); // assume no item was clicked - Fl_Tree_Item *o = _root->find_clicked(); - if ( o ) { - ret |= 1; // handled - if ( Fl::event_button() == FL_LEFT_MOUSE ) { - // Was collapse icon clicked? - if ( o->event_on_collapse_icon(_prefs) ) { - o->open_toggle(); - redraw(); - } - // Item's label clicked? - else if ( o->event_on_label(_prefs) && - (!o->widget() || !Fl::event_inside(o->widget())) && - callback() && - (!_vscroll->visible() || !Fl::event_inside(_vscroll)) ) { - item_clicked(o); // save item clicked - // Handle selection behavior - switch ( _prefs.selectmode() ) { - case FL_TREE_SELECT_NONE: { // no selection changes - break; - } - case FL_TREE_SELECT_SINGLE: { - changed = select_only(o); - break; - } - case FL_TREE_SELECT_MULTI: { - int state = Fl::event_state(); - if ( state & FL_SHIFT ) { - if ( ! o->is_selected() ) { - o->select(); // add to selection - changed = 1; // changed - } - } else if ( state & FL_CTRL ) { - changed = 1; // changed - o->select_toggle(); // toggle selection state - lastselect = o; // save we toggled it (prevents oscillation) - } else { - changed = select_only(o); - } - break; - } - } - if ( changed ) { - redraw(); // make change(s) visible - if ( when() & FL_WHEN_CHANGED ) { - set_changed(); - do_callback((Fl_Widget*)this, user_data()); // item callback - } - } - } - } - } - break; - } - case FL_DRAG: { - Fl_Tree_Item *o = _root->find_clicked(); - if ( o ) { - ret |= 1; // handled - // Item's label clicked? - if ( o->event_on_label(_prefs) && - (!o->widget() || !Fl::event_inside(o->widget())) && - callback() && - (!_vscroll->visible() || !Fl::event_inside(_vscroll)) ) { - item_clicked(o); // save item clicked - // Handle selection behavior - switch ( _prefs.selectmode() ) { - case FL_TREE_SELECT_NONE: { // no selection changes - break; - } - case FL_TREE_SELECT_SINGLE: { - changed = select_only(o); - break; - } - case FL_TREE_SELECT_MULTI: { - int state = Fl::event_state(); - if ( state & FL_CTRL ) { - if ( lastselect != o ) {// not already toggled from last microdrag? - changed = 1; // changed - o->select_toggle(); // toggle selection - lastselect = o; // save we toggled it (prevents oscillation) - redraw(); // make change(s) visible - } - } else { - changed = 1; // changed - o->select(); // select this - redraw(); // make change(s) visible - } - break; - } - } - if ( changed ) { - redraw(); // make change(s) visible - if ( when() & FL_WHEN_CHANGED ) { - set_changed(); - do_callback((Fl_Widget*)this, user_data()); // item callback - } - } - } - } - } - case FL_RELEASE: { - if ( Fl::event_button() == FL_LEFT_MOUSE ) { - ret |= 1; - } - break; - } - } - return(ret); -} - -/// Deselect item and all its children. -/// If item is NULL, root() is used. -/// Handles calling redraw() if anything was changed. -/// Returns count of how many items were in the 'selected' state, -/// ie. how many items were "changed". -/// -int Fl_Tree::deselect_all(Fl_Tree_Item *item) { - item = item ? item : root(); // NULL? use root() - int count = item->deselect_all(); - if ( count ) redraw(); // anything changed? cause redraw - return(count); -} - -/// Select only this item. -/// If item is NULL, root() is used. -/// Handles calling redraw() if anything was changed. -/// Returns how many items were changed, if any. -/// -int Fl_Tree::select_only(Fl_Tree_Item *selitem) { - selitem = selitem ? selitem : root(); // NULL? use root() - int changed = 0; - for ( Fl_Tree_Item *item = first(); item; item = item->next() ) { - if ( item == selitem ) { - if ( item->is_selected() ) continue; // don't count if already selected - item->select(); - ++changed; - } else { - if ( item->is_selected() ) { - item->deselect(); - ++changed; - } - } - } - if ( changed ) redraw(); // anything changed? redraw - return(changed); -} diff --git a/contrib/Fl_Tree/Fl_Tree_Item.cxx b/contrib/Fl_Tree/Fl_Tree_Item.cxx deleted file mode 100644 index dc99b7fa7ecf9cb37309522fc39470e431aaefa6..0000000000000000000000000000000000000000 --- a/contrib/Fl_Tree/Fl_Tree_Item.cxx +++ /dev/null @@ -1,693 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <FL/Fl_Widget.H> -#include <FL/Fl_Tree_Item.H> -#include <FL/Fl_Tree_Prefs.H> - -////////////////////// -// Fl_Tree_Item.cxx -////////////////////// -// -// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK -// Copyright (C) 2009 by Greg Ercolano. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// USA. -// - -// Was the last event inside the specified xywh? -static int event_inside(const int xywh[4]) { - return(Fl::event_inside(xywh[0],xywh[1],xywh[2],xywh[3])); -} - -/// Constructor. -/// Makes a new instance of Fl_Tree_Item using defaults from 'prefs'. -/// -Fl_Tree_Item::Fl_Tree_Item(const Fl_Tree_Prefs &prefs) { - _label = 0; - _labelfont = prefs.labelfont(); - _labelsize = prefs.labelsize(); - _labelfgcolor = prefs.fgcolor(); - _labelbgcolor = prefs.bgcolor(); - _widget = 0; - _open = 1; - _visible = 1; - _active = 1; - _selected = 0; - _xywh[0] = 0; - _xywh[1] = 0; - _xywh[2] = 0; - _xywh[3] = 0; - _collapse_xywh[0] = 0; - _collapse_xywh[1] = 0; - _collapse_xywh[2] = 0; - _collapse_xywh[3] = 0; - _label_xywh[0] = 0; - _label_xywh[1] = 0; - _label_xywh[2] = 0; - _label_xywh[3] = 0; - _usericon = 0; - _userdata = 0; // GMSH - _parent = 0; -} - -// DTOR -Fl_Tree_Item::~Fl_Tree_Item() { - if ( _label ) { - free((void*)_label); - _label = 0; - } - _widget = 0; // Fl_Group will handle destruction - _usericon = 0; // user handled allocation - //_children.clear(); // array's destructor handles itself -} - -/// Copy constructor. -Fl_Tree_Item::Fl_Tree_Item(const Fl_Tree_Item *o) { - _label = o->label() ? strdup(o->label()) : 0; - _labelfont = o->labelfont(); - _labelsize = o->labelsize(); - _labelfgcolor = o->labelfgcolor(); - _labelbgcolor = o->labelbgcolor(); - _widget = o->widget(); - _open = o->_open; - _visible = o->_visible; - _active = o->_active; - _selected = o->_selected; - _xywh[0] = o->_xywh[0]; - _xywh[1] = o->_xywh[1]; - _xywh[2] = o->_xywh[2]; - _xywh[3] = o->_xywh[3]; - _collapse_xywh[0] = o->_collapse_xywh[0]; - _collapse_xywh[1] = o->_collapse_xywh[1]; - _collapse_xywh[2] = o->_collapse_xywh[2]; - _collapse_xywh[3] = o->_collapse_xywh[3]; - _label_xywh[0] = o->_label_xywh[0]; - _label_xywh[1] = o->_label_xywh[1]; - _label_xywh[2] = o->_label_xywh[2]; - _label_xywh[3] = o->_label_xywh[3]; - _usericon = o->usericon(); - _parent = o->_parent; -} - -/// Print the tree as 'ascii art' to stdout. -/// Used mainly for debugging. -/// -void Fl_Tree_Item::show_self(const char *indent) const { - if ( label() ) { - printf("%s-%s (%d children, this=%p, parent=%p depth=%d)\n", - indent,label(),children(),(void*)this, (void*)_parent, depth()); - } - if ( children() ) { - char *i2 = (char*)malloc(strlen(indent) + 2); - strcpy(i2, indent); - strcat(i2, " |"); - for ( int t=0; t<children(); t++ ) { - child(t)->show_self(i2); - } - } - fflush(stdout); -} - -/// Set the label. Makes a copy of the name. -void Fl_Tree_Item::label(const char *name) { - if ( _label ) { free((void*)_label); _label = 0; } - _label = name ? strdup(name) : 0; -} - -/// Return the label. -const char *Fl_Tree_Item::label() const { - return(_label); -} - -/// Return child item for the specified 'index'. -const Fl_Tree_Item *Fl_Tree_Item::child(int index) const { - return(_children[index]); -} - -/// Clear all the children for this item. -void Fl_Tree_Item::clear_children() { - _children.clear(); -} - -/// Return the index of the immediate child of this item that has the label 'name'. -/// -/// \returns index of found item, or -1 if not found. -/// -int Fl_Tree_Item::find_child(const char *name) { - for ( int t=0; t<children(); t++ ) { - if ( child(t)->label() ) { - if ( strcmp(child(t)->label(), name) == 0 ) { - return(t); - } - } - } - return(-1); -} - -/// Find item by descending array of names. -/// Only Fl_Tree should need this method. -/// -/// \returns item, or 0 if not found -/// -const Fl_Tree_Item *Fl_Tree_Item::find_item(char **arr) const { - for ( int t=0; t<children(); t++ ) { - if ( child(t)->label() ) { - if ( strcmp(child(t)->label(), *arr) == 0 ) { // match? - if ( *(arr+1) ) { // more in arr? descend - return(_children[t]->find_item(arr+1)); - } else { // end of arr? done - return(_children[t]); - } - } - } - } - return(0); -} - -/// Find item by by descending array of names. -/// Only Fl_Tree should need this method. -/// -/// \returns item, or 0 if not found -/// -Fl_Tree_Item *Fl_Tree_Item::find_item(char **arr) { - for ( int t=0; t<children(); t++ ) { - if ( child(t)->label() ) { - if ( strcmp(child(t)->label(), *arr) == 0 ) { // match? - if ( *(arr+1) ) { // more in arr? descend - return(_children[t]->find_item(arr+1)); - } else { // end of arr? done - return(_children[t]); - } - } - } - } - return(0); -} - -/// Find the index number for the specified 'item' -/// in the current item's list of children. -/// -/// \returns the index, or -1 if not found. -/// -int Fl_Tree_Item::find_child(Fl_Tree_Item *item) { - for ( int t=0; t<children(); t++ ) { - if ( item == child(t) ) { - return(t); - } - } - return(-1); -} - -/// Add a new child to this item with the name 'new_label', with defaults from 'prefs'. -/// An internally managed copy is made of the label string. -/// Adds the item based on the value of prefs.sortorder(). -/// -Fl_Tree_Item *Fl_Tree_Item::add(const Fl_Tree_Prefs &prefs, const char *new_label) { - Fl_Tree_Item *item = new Fl_Tree_Item(prefs); - item->label(new_label); - item->_parent = this; - switch ( prefs.sortorder() ) { - case FL_TREE_SORT_NONE: { - _children.add(item); - return(item); - } - case FL_TREE_SORT_ASCENDING: { - for ( int t=0; t<_children.total(); t++ ) { - Fl_Tree_Item *c = _children[t]; - if ( c->label() && strcmp(c->label(), new_label) > 0 ) { - _children.insert(t, item); - return(item); - } - } - _children.add(item); - return(item); - } - case FL_TREE_SORT_DESCENDING: { - for ( int t=0; t<_children.total(); t++ ) { - Fl_Tree_Item *c = _children[t]; - if ( c->label() && strcmp(c->label(), new_label) < 0 ) { - _children.insert(t, item); - return(item); - } - } - _children.add(item); - return(item); - } - } - return(item); -} - -/// Add a child recursively into tree. -/// Should be used only by Fl_Tree's internals. -/// Adds the item based on the value of prefs.sortorder(). -/// -Fl_Tree_Item *Fl_Tree_Item::add(const Fl_Tree_Prefs &prefs, char **arr) { - int t = find_child(*arr); - Fl_Tree_Item *item; - if ( t == -1 ) { - item = (Fl_Tree_Item*)add(prefs, *arr); - } else { - item = (Fl_Tree_Item*)child(t); - } - if ( *(arr+1) ) { // descend? - return(item->add(prefs, arr+1)); - } else { - return(item); // end? done - } -} - -/// Insert a new item into current item's children at a specified position. -Fl_Tree_Item *Fl_Tree_Item::insert(const Fl_Tree_Prefs &prefs, const char *new_label, int pos) { - Fl_Tree_Item *item = new Fl_Tree_Item(prefs); - item->label(new_label); - item->_parent = this; - _children.insert(pos, item); - return(item); -} - -/// Insert a new item above this item. -Fl_Tree_Item *Fl_Tree_Item::insert_above(const Fl_Tree_Prefs &prefs, const char *new_label) { - Fl_Tree_Item *p = _parent; - if ( ! p ) return(0); - // Walk our parent's children to find ourself - for ( int t=0; t<p->children(); t++ ) { - Fl_Tree_Item *c = p->child(t); - if ( this == c ) { - return(p->insert(prefs, new_label, t)); - } - } - return(0); -} - -/// Remove child by item. -/// Returns 0 if removed, -1 if item not an immediate child. -/// -int Fl_Tree_Item::remove_child(Fl_Tree_Item *item) { - for ( int t=0; t<children(); t++ ) { - if ( child(t) == item ) { - item->clear_children(); - _children.remove(t); - return(0); - } - } - return(-1); -} - -/// Remove immediate child (and its children) by its label 'name'. -/// Returns 0 if removed, -1 if not found. -/// -int Fl_Tree_Item::remove_child(const char *name) { - for ( int t=0; t<children(); t++ ) { - if ( child(t)->label() ) { - if ( strcmp(child(t)->label(), name) == 0 ) { - _children.remove(t); - return(0); - } - } - } - return(-1); -} - -/// Swap two of our children, given two child index values. -/// Use this eg. for sorting. -/// -/// This method is FAST, and does not involve lookups. -/// -/// No range checking is done on either index value. -/// -/// \returns -/// - 0 : OK -/// - -1 : failed: 'a' or 'b' is not our immediate child -/// -void Fl_Tree_Item::swap_children(int ax, int bx) { - _children.swap(ax, bx); -} - -/// Swap two of our children, given item pointers. -/// Use this eg. for sorting. -/// -/// This method is SLOW because it involves linear lookups. -/// For speed, use swap_children(int,int) instead. -/// -/// \returns -/// - 0 : OK -/// - -1 : failed: 'a' or 'b' is not our immediate child -/// -int Fl_Tree_Item::swap_children(Fl_Tree_Item *a, Fl_Tree_Item *b) { - int ax = -1, bx = -1; - for ( int t=0; t<children(); t++ ) { // find index for a and b - if ( _children[t] == a ) { ax = t; if ( bx != -1 ) break; else continue; } - if ( _children[t] == b ) { bx = t; if ( ax != -1 ) break; else continue; } - } - if ( ax == -1 || bx == -1 ) return(-1); // not found? fail - swap_children(ax,bx); - return(0); -} - -/// Internal: Horizontal connector line based on preference settings. -void Fl_Tree_Item::draw_horizontal_connector(int x1, int x2, int y, const Fl_Tree_Prefs &prefs) { - fl_color(prefs.connectorcolor()); - switch ( prefs.connectorstyle() ) { - case FL_TREE_CONNECTOR_SOLID: - y |= 1; // force alignment w/dot pattern - fl_line(x1,y,x2,y); - return; - case FL_TREE_CONNECTOR_DOTTED: - y |= 1; // force alignment w/dot pattern - for ( int xx=x1; xx<=x2; xx++ ) { - if ( !(xx & 1) ) fl_point(xx, y); - } - return; - case FL_TREE_CONNECTOR_NONE: - return; - } -} - -/// Internal: Vertical connector line based on preference settings. -void Fl_Tree_Item::draw_vertical_connector(int x, int y1, int y2, const Fl_Tree_Prefs &prefs) { - fl_color(prefs.connectorcolor()); - switch ( prefs.connectorstyle() ) { - case FL_TREE_CONNECTOR_SOLID: - y1 |= 1; // force alignment w/dot pattern - y2 |= 1; // force alignment w/dot pattern - fl_line(x,y1,x,y2); - return; - case FL_TREE_CONNECTOR_DOTTED: - y1 |= 1; // force alignment w/dot pattern - y2 |= 1; // force alignment w/dot pattern - for ( int yy=y1; yy<=y2; yy++ ) { - if ( yy & 1 ) fl_point(x, yy); - } - return; - case FL_TREE_CONNECTOR_NONE: - return; - } -} - -/// Find the item that the last event was over. -/// -/// Returns the item if its visible, and mouse is over it. -/// Works even if widget deactivated. -/// Use event_on_collapse_icon() to determine if collapse button was pressed. -/// -/// \returns const visible item under the event if found, or 0 if none. -/// -const Fl_Tree_Item *Fl_Tree_Item::find_clicked() const { - if ( ! _visible ) return(0); - if ( event_inside(_xywh) ) { // event within this item? - return(this); // found - } - if ( is_open() ) { // open? check children of this item - for ( int t=0; t<children(); t++ ) { - const Fl_Tree_Item *item; - if ( ( item = _children[t]->find_clicked() ) != NULL) { // check child and its descendents - return(item); // found? - } - } - } - return(0); -} - -/// Non-const version of the above. -/// Find the item that the last event was over. -/// -/// Returns the item if its visible, and mouse is over it. -/// Works even if widget deactivated. -/// Use event_on_collapse_icon() to determine if collapse button was pressed. -/// -/// \returns the visible item under the event if found, or 0 if none. -/// -Fl_Tree_Item *Fl_Tree_Item::find_clicked() { - if ( ! _visible ) return(0); - if ( event_inside(_xywh) ) { // event within this item? - return(this); // found - } - if ( is_open() ) { // open? check children of this item - for ( int t=0; t<children(); t++ ) { - Fl_Tree_Item *item; - if ( ( item = _children[t]->find_clicked() ) != NULL ) { // check child and its descendents - return(item); // found? - } - } - } - return(0); -} - -/// Draw this item and its children. -void Fl_Tree_Item::draw(int X, int &Y, int W, Fl_Widget *tree, - const Fl_Tree_Prefs &prefs, int lastchild) { - if ( ! _visible ) return; - fl_font(_labelfont, _labelsize); - int H = _labelsize + fl_descent() + prefs.linespacing(); - // Colors, fonts - Fl_Color fg = _selected ? prefs.bgcolor() : _labelfgcolor; - Fl_Color bg = _selected ? prefs.selectcolor() : _labelbgcolor; - if ( ! _active ) { - fg = fl_inactive(fg); - if ( _selected ) bg = fl_inactive(bg); - } - // Update the xywh of this item - _xywh[0] = X; - _xywh[1] = Y; - _xywh[2] = W; - _xywh[3] = H; - // Text size - int textw=0, texth=0; - fl_measure(_label, textw, texth, 0); - int textycenter = Y+(H/2); - int &icon_x = _collapse_xywh[0] = X-1; - int &icon_y = _collapse_xywh[1] = textycenter - (prefs.openicon()->h()/2); - int &icon_w = _collapse_xywh[2] = prefs.openicon()->w(); - _collapse_xywh[3] = prefs.openicon()->h(); - // Horizontal connector values - int hstartx = X+icon_w/2-1; - int hendx = hstartx + prefs.connectorwidth(); - int hcenterx = X + icon_w + ((hendx - (X + icon_w)) / 2); - - // See if we should draw this item - // If this item is root, and showroot() is disabled, don't draw. - // - char drawthis = ( is_root() && prefs.showroot() == 0 ) ? 0 : 1; - if ( drawthis ) { - // Draw connectors - if ( prefs.connectorstyle() != FL_TREE_CONNECTOR_NONE ) { - // Horiz connector between center of icon and text - draw_horizontal_connector(hstartx, hendx, textycenter, prefs); - if ( has_children() && is_open() ) { - // Small vertical line down to children - draw_vertical_connector(hcenterx, textycenter, Y+H, prefs); - } - // Connectors for last child - if ( ! is_root() ) { - if ( lastchild ) { - draw_vertical_connector(hstartx, Y, textycenter, prefs); - } else { - draw_vertical_connector(hstartx, Y, Y+H, prefs); - } - } - } - // Draw collapse icon - if ( has_children() && prefs.showcollapse() ) { - // Draw icon image - if ( is_open() ) { - prefs.closeicon()->draw(icon_x,icon_y); - } else { - prefs.openicon()->draw(icon_x,icon_y); - } - } - // Background for this item - int &bx = _label_xywh[0] = X+(icon_w/2-1+prefs.connectorwidth()); - int &by = _label_xywh[1] = Y; - int &bw = _label_xywh[2] = W-(icon_w/2-1+prefs.connectorwidth()); - int &bh = _label_xywh[3] = texth; - // Draw bg only if different from tree's bg - if ( bg != tree->color() || is_selected() ) { - if ( is_selected() ) { - // Selected? Use selectbox() style - fl_draw_box(prefs.selectbox(), bx, by, bw, bh, bg); - } else { - // Not Selected? use plain filled rectangle - fl_color(bg); - fl_rectf(bx, by, bw, bh); - } - } - // Draw user icon (if any) - int useroff = (icon_w/2-1+prefs.connectorwidth()); - if ( usericon() ) { - // Item has user icon? Use it - useroff += prefs.usericonmarginleft(); - usericon()->draw(X+useroff,icon_y); - useroff += usericon()->w(); - } else if ( prefs.usericon() ) { - // Prefs has user icon? Use it - useroff += prefs.usericonmarginleft(); - prefs.usericon()->draw(X+useroff,icon_y); - useroff += prefs.usericon()->w(); - } - useroff += prefs.labelmarginleft(); - // Draw label - if ( widget() ) { - // Widget? Draw it - int lx = X+useroff; - int ly = by; - int lw = widget()->w(); - int lh = bh; - if ( widget()->x() != lx || widget()->y() != ly || - widget()->w() != lw || widget()->h() != lh ) { - widget()->resize(lx, ly, lw, lh); // fltk will handle drawing this - } - } else { - // No label widget? Draw text label - if ( _label ) { - fl_color(fg); - fl_draw(_label, X+useroff, Y+H-fl_descent()-1); - } - } - Y += H; - } // end drawthis - // Draw children - if ( has_children() && is_open() ) { - int child_x = drawthis ? // offset children to right, - (hcenterx - (icon_w/2) + 1) : X; // unless didn't drawthis - int child_w = W - (child_x-X); - int child_y_start = Y; - for ( int t=0; t<children(); t++ ) { - int lastchild = ((t+1)==children()) ? 1 : 0; - _children[t]->draw(child_x, Y, child_w, tree, prefs, lastchild); - } - if ( ! lastchild ) { - draw_vertical_connector(hstartx, child_y_start, Y, prefs); - } - } -} - -/// Was the event on the 'collapse' button? -/// -int Fl_Tree_Item::event_on_collapse_icon(const Fl_Tree_Prefs &prefs) const { - if ( _visible && _active && has_children() && prefs.showcollapse() ) { - return(event_inside(_collapse_xywh) ? 1 : 0); - } else { - return(0); - } -} - -/// Was event on the label()? -/// -int Fl_Tree_Item::event_on_label(const Fl_Tree_Prefs &prefs) const { - if ( _visible && _active ) { - return(event_inside(_label_xywh) ? 1 : 0); - } else { - return(0); - } -} - -/// Internal: Show the FLTK widget() for this item and all children. -/// Used by open() to re-show widgets that were hidden by a previous close() -/// -void Fl_Tree_Item::show_widgets() { - if ( _widget ) _widget->show(); - if ( is_open() ) { - for ( int t=0; t<_children.total(); t++ ) { - _children[t]->show_widgets(); - } - } -} - -/// Internal: Hide the FLTK widget() for this item and all children. -/// Used by close() to hide widgets. -/// -void Fl_Tree_Item::hide_widgets() { - if ( _widget ) _widget->hide(); - for ( int t=0; t<_children.total(); t++ ) { - _children[t]->hide_widgets(); - } -} - -/// Open this item and all its children. -void Fl_Tree_Item::open() { - _open = 1; - // Tell children to show() their widgets - for ( int t=0; t<_children.total(); t++ ) { - _children[t]->show_widgets(); - } -} - -/// Close this item and all its children. -void Fl_Tree_Item::close() { - _open = 0; - // Tell children to hide() their widgets - for ( int t=0; t<_children.total(); t++ ) { - _children[t]->hide_widgets(); - } -} - -/// Returns how many levels deep this item is in the hierarchy. -/// -/// For instance; root has a depth of zero, and its immediate children -/// would have a depth of 1, and so on. -/// -int Fl_Tree_Item::depth() const { - int count = 0; - const Fl_Tree_Item *item = parent(); - while ( item ) { - ++count; - item = item->parent(); - } - return(count); -} - -/// Return the next item in the tree. -/// -/// This method can be used to walk the tree forward. -/// For an example of how to use this method, see Fl_Tree::first(). -/// -/// \returns the next item in the tree, or 0 if there's no more items. -/// -Fl_Tree_Item *Fl_Tree_Item::next() { - Fl_Tree_Item *p, *c = this; - if ( c->has_children() ) { - return(c->child(0)); - } - while ( ( p = c->parent() ) != NULL ) { // loop upwards through parents - int t = p->find_child(c); // find our position in parent's children[] array - if ( ++t < p->children() ) // not last child? - return(p->child(t)); // return next child - c = p; // child becomes parent to move up generation - } // loop: moves up to next parent - return(0); // hit root? done -} - -/// Return the previous item in the tree. -/// -/// This method can be used to walk the tree backwards. -/// For an example of how to use this method, see Fl_Tree::last(). -/// -/// \returns the previous item in the tree, or 0 if there's no item above this one (hit the root). -/// -Fl_Tree_Item *Fl_Tree_Item::prev() { - Fl_Tree_Item *p=parent(); // start with parent - if ( ! p ) return(0); // hit root? done - int t = p->find_child(this); // find our position in parent's children[] array - if ( --t == -1 ) { // are we first child? - return(p); // return immediate parent - } - p = p->child(t); // take parent's previous child - while ( p->has_children() ) { // has children? - p = p->child(p->children()-1); // take last child - } - return(p); -} diff --git a/contrib/Fl_Tree/Fl_Tree_Item_Array.cxx b/contrib/Fl_Tree/Fl_Tree_Item_Array.cxx deleted file mode 100644 index a26a8a217dbf56541739f1472ecfc095149196a3..0000000000000000000000000000000000000000 --- a/contrib/Fl_Tree/Fl_Tree_Item_Array.cxx +++ /dev/null @@ -1,149 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <FL/Fl_Tree_Item_Array.H> -#include <FL/Fl_Tree_Item.H> - -////////////////////// -// Fl_Tree_Item_Array.cxx -////////////////////// -// -// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK -// Copyright (C) 2009 by Greg Ercolano. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// USA. -// - -/// Constructor; creates an empty array. -/// -/// The optional 'chunksize' can be specified to optimize -/// memory allocation for potentially large arrays. Default chunksize is 10. -/// -Fl_Tree_Item_Array::Fl_Tree_Item_Array(int new_chunksize) { - _items = 0; - _total = 0; - _size = 0; - _chunksize = new_chunksize; -} - -/// Destructor. Calls each item's destructor, destroys internal _items array. -Fl_Tree_Item_Array::~Fl_Tree_Item_Array() { - clear(); -} - -/// Copy constructor. Makes new copy of array, with new instances of each item. -Fl_Tree_Item_Array::Fl_Tree_Item_Array(const Fl_Tree_Item_Array* o) { - _items = (Fl_Tree_Item**)malloc(o->_size * sizeof(Fl_Tree_Item*)); - _total = o->_total; - _size = o->_size; - _chunksize = o->_chunksize; - for ( int t=0; t<o->_total; t++ ) { - _items[t] = new Fl_Tree_Item(o->_items[t]); - } -} - -/// Clear the entire array. -/// -/// Each item will be deleted (destructors will be called), -/// and the array will be cleared. total() will return 0. -/// -void Fl_Tree_Item_Array::clear() { - if ( _items ) { - for ( int t=0; t<_total; t++ ) { - delete _items[t]; - _items[t] = 0; - } - free((void*)_items); _items = 0; - } - _total = _size = 0; -} - -// Internal: Enlarge the items array. -// -// Adjusts size/items memory allocation as needed. -// Does NOT change total. -// -void Fl_Tree_Item_Array::enlarge(int count) { - int newtotal = _total + count; // new total - if ( newtotal >= _size ) { // more than we have allocated? - // Increase size of array - int newsize = _size + _chunksize; - Fl_Tree_Item **newitems = (Fl_Tree_Item**)malloc(newsize * sizeof(Fl_Tree_Item*)); - if ( _items ) { - // Copy old array -> new, delete old - memmove(newitems, _items, _size * sizeof(Fl_Tree_Item*)); - free((void*)_items); _items = 0; - } - // Adjust items/sizeitems - _items = newitems; - _size = newsize; - } -} - -/// Insert an item at index position \p pos. -/// -/// Handles enlarging array if needed, total increased by 1. -/// If \p pos == total(), an empty item is appended to the array. -/// -void Fl_Tree_Item_Array::insert(int pos, Fl_Tree_Item *new_item) { - enlarge(1); - // printf("*** POS=%d TOTAL-1=%d NITEMS=%d\n", pos, _total-1, (_total-pos)); - if ( pos <= (_total - 1) ) { // need to move memory around? - int nitems = _total - pos; - memmove(&_items[pos+1], &_items[pos], sizeof(Fl_Tree_Item*) * nitems); - } - _items[pos] = new_item; - _total++; -} - -/// Add an item* to the end of the array. -/// -/// Assumes the item was created with 'new', and will remain -/// allocated.. Fl_Tree_Item_Array will handle calling the -/// item's destructor when the array is cleared or the item remove()'ed. -/// -void Fl_Tree_Item_Array::add(Fl_Tree_Item *val) { - insert(_total, val); -} - -/// Remove the item at \param[in] index from the array. -/// -/// The item will be delete'd (if non-NULL), so its destructor will be called. -/// -void Fl_Tree_Item_Array::remove(int index) { - if ( _items[index] ) { // delete if non-zero - delete _items[index]; - } - _items[index] = 0; - for ( _total--; index<_total; index++ ) { - _items[index] = _items[index+1]; - } -} - -/// Remove the item from the array. -/// -/// \returns 0 if removed, or -1 if the item was not in the array. -/// -int Fl_Tree_Item_Array::remove(Fl_Tree_Item *item) { - for ( int t=0; t<_total; t++ ) { - if ( item == _items[t] ) { - remove(t); - return(0); - } - } - return(-1); -} diff --git a/contrib/Fl_Tree/Fl_Tree_Prefs.cxx b/contrib/Fl_Tree/Fl_Tree_Prefs.cxx deleted file mode 100644 index 22f3e56db1cb3ef035910e822efa8e2dd7b3b27c..0000000000000000000000000000000000000000 --- a/contrib/Fl_Tree/Fl_Tree_Prefs.cxx +++ /dev/null @@ -1,126 +0,0 @@ -#include <string.h> -#include <FL/Fl.H> -#include <FL/Fl_Pixmap.H> -#include <FL/Fl_Tree_Prefs.H> - -////////////////////// -// Fl_Tree_Prefs.cxx -////////////////////// -// -// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK -// Copyright (C) 2009 by Greg Ercolano. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// USA. -// - -// INTERNAL: BUILT IN OPEN/STOW XPMS -// These can be replaced via prefs.openicon()/closeicon() -// -static const char *L_open_xpm[] = { - "11 11 3 1", - ". c #fefefe", - "# c #444444", - "@ c #000000", - "###########", - "#.........#", - "#.........#", - "#....@....#", - "#....@....#", - "#..@@@@@..#", - "#....@....#", - "#....@....#", - "#.........#", - "#.........#", - "###########"}; -static Fl_Pixmap L_openpixmap(L_open_xpm); - -static const char *L_close_xpm[] = { - "11 11 3 1", - ". c #fefefe", - "# c #444444", - "@ c #000000", - "###########", - "#.........#", - "#.........#", - "#.........#", - "#.........#", - "#..@@@@@..#", - "#.........#", - "#.........#", - "#.........#", - "#.........#", - "###########"}; -static Fl_Pixmap L_closepixmap(L_close_xpm); - -/// Sets the default icon to be used as the 'open' icon -/// when items are add()ed to the tree. -/// This overrides the built in default '[+]' icon. -/// -/// \param[in] val -- The new pixmap, or zero to use the default [+] icon. -/// -void Fl_Tree_Prefs::openicon(Fl_Pixmap *val) { - _openpixmap = val ? val : &L_openpixmap; -} - -/// Sets the icon to be used as the 'close' icon. -/// This overrides the built in default '[-]' icon. -/// -/// \param[in] val -- The new pixmap, or zero to use the default [-] icon. -/// -void Fl_Tree_Prefs::closeicon(Fl_Pixmap *val) { - _closepixmap = val ? val : &L_closepixmap; -} - -/// Fl_Tree_Prefs constructor -Fl_Tree_Prefs::Fl_Tree_Prefs() { - _labelfont = FL_HELVETICA; - _labelsize = FL_NORMAL_SIZE; - _marginleft = 6; - _margintop = 3; - //_marginright = 3; - //_marginbottom = 3; - _usericonmarginleft = 3; - _labelmarginleft = 3; - _linespacing = 0; - _fgcolor = FL_BLACK; - _bgcolor = FL_WHITE; - _selectcolor = FL_DARK_BLUE; - _inactivecolor = FL_GRAY; - _connectorcolor = Fl_Color(43); - _connectorstyle = FL_TREE_CONNECTOR_DOTTED; - _openpixmap = &L_openpixmap; - _closepixmap = &L_closepixmap; - _userpixmap = 0; - _showcollapse = 1; - _showroot = 1; - _connectorwidth = 17; - _sortorder = FL_TREE_SORT_NONE; - _selectbox = FL_FLAT_BOX; - _selectmode = FL_TREE_SELECT_SINGLE; - // Let fltk's current 'scheme' affect defaults - if ( Fl::scheme() ) { - if ( strcmp(Fl::scheme(), "gtk+") == 0 ) { -#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 1) && (FL_PATCH_VERSION < 9) - // GMSH PATCH for fltk < 1.1.9 compat - _selectbox = FL_FLAT_BOX; -#else - _selectbox = _FL_GTK_THIN_UP_BOX; -#endif - } else if ( strcmp(Fl::scheme(), "plastic") == 0 ) { - _selectbox = _FL_PLASTIC_THIN_UP_BOX; - } - } -} diff --git a/contrib/Fl_Tree/README.txt b/contrib/Fl_Tree/README.txt deleted file mode 100644 index 11e93a406035ccede01fc868b7649be87c3d344a..0000000000000000000000000000000000000000 --- a/contrib/Fl_Tree/README.txt +++ /dev/null @@ -1,56 +0,0 @@ - -This is a slightly modified version of the Fl_Tree widget for -Gmsh. The following modifications (marked with "GMSH" in the source -code) were applied: - - - added userdata() membre to Fl_Tree_Item so we can store user data - in each node - - -Fl_Tree -- FLTK 'Tree' Widget ------------------------------------- - -WHAT IS "Fl_Tree"? - - Fl_Tree is a 'tree' widget aimed at becoming part of the FLTK's core, - or fltk extensions library. - -LICENSING - - Fl_Tree comes with complete free source code. - Fl_Tree is available under the terms of the GNU Library - General Public License. See COPYING for more info. - - Contrary to popular belief, it can be used in commercial - software! - -BUILD INSTRUCTIONS - - Tested under Linux and Mac OSX with fltk 1.1.9. - (TBD: Windows, though will probably compile+run OK) - - To build the test programs and related Fl_Tree object files: - - make - - These test programs are created: - - test-simple -- Simple example of how to use the Fl_Tree widget - test-Fl_Tree -- Exerciser app to test Fl_Tree's features - -WHERE'S THE DOCUMENTATION? - - See documentation/html/index.html - - The docs are in ./documentation/html and are doxyen based - (comments in code), and can be re-generated by running - 'make docs' or by simply running 'doxygen' while in ./documentation. - - -RELEASE NOTES/VERSION INFORMATION - - See ./CHANGES - -BUGS? - - Send them to erco at seriss dot com diff --git a/demos/indheat.geo b/demos/indheat.geo index f706faed031d8118d07e2de160b8b0cec4fb9abe..5e7c22fe4f7c2ab0aef01b80b48d3b498415356a 100644 --- a/demos/indheat.geo +++ b/demos/indheat.geo @@ -13,10 +13,10 @@ DefineConstant lb = {1, Label "Infinite box width"}, left = {1, Choices{0,1}, Label "Terminals on the left?"} //macro = {"aa.pos", Label "Run my macro!", Kind "macro", Path "Actions"}, - // showLines = {1, Choices {0,1}, Label "Show lines?"} + showLines = {1, Choices {0,1}, Label "Show lines?"} ]; -//Geometry.Lines = showLines; +Geometry.Lines = showLines; // inductor p = newp; diff --git a/doc/CREDITS.txt b/doc/CREDITS.txt index e363db09ba1d78e77c82d8f074efc80256764e71..90968526a119830abaa3fdf3a48101b110776572 100644 --- a/doc/CREDITS.txt +++ b/doc/CREDITS.txt @@ -66,9 +66,6 @@ written by Bruce Hendrickson and Robert Leland at Sandia National Laboratories under US Department of Energy contract DE-AC04-76DP00789 and is copyrighted by Sandia Corporation: check the configuration options. -This version of Gmsh may contain code (in the contrib/Fl_Tree subdirectory), -copyright (C) 2009 Greg Ercolano: check the configuration options. - This version of Gmsh may contain code (in the contrib/gmm subdirectory) copyright (C) 2002-2008 Yves Renard: check the configuration options. diff --git a/doc/VERSIONS.txt b/doc/VERSIONS.txt index b2cdce7bbe5f2b3e06a92a9c04243e91e9eb6968..b90079573319e0b17027be726ef97680303157f0 100644 --- a/doc/VERSIONS.txt +++ b/doc/VERSIONS.txt @@ -1,4 +1,5 @@ -faster STEP/BRep import; minor bug fixes. +?: new single-window GUI, with dynamically customizable widget tree; faster +STEP/BRep import; minor bug fixes. 2.6.1 (July 15, 2012): minor improvements and bug fixes.