Select Git revision
PViewDataIO.cpp
-
Christophe Geuzaine authoredChristophe Geuzaine authored
GUI.cpp 172.39 KiB
// $Id: GUI.cpp,v 1.610 2007-05-04 16:22:37 geuzaine Exp $
//
// Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// Please report all bugs and problems to <gmsh@geuz.org>.
#include "Gmsh.h"
#include "GmshUI.h"
#include "GmshDefines.h"
#include "Numeric.h"
#include "Context.h"
#include "Options.h"
#include "Draw.h"
#include "GUI.h"
#include "Callbacks.h"
#include "Bitmaps.h"
#include "Win32Icon.h"
#include "OpenFile.h"
#include "CommandLine.h"
#include "Generator.h"
#include "Solvers.h"
#include "PluginManager.h"
#include "Shortcut_Window.h"
#define NB_BUTT_SCROLL 25
#define NB_HISTORY_MAX 1000
#define IW (10*fontsize) // input field width
#define BB (7*fontsize) // width of a button with internal label
#define BH (2*fontsize+1) // button height
#define WB (7) // window border
extern Context_T CTX;
// Definition of the static menus (we cannot use the 'g', 'm' 's' and
// 'p' mnemonics since they are already defined as global shortcuts)
Fl_Menu_Item m_menubar_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},
{"M&erge...", FL_CTRL+FL_SHIFT+'o', (Fl_Callback *)file_merge_cb, 0, FL_MENU_DIVIDER},
{"&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, FL_MENU_DIVIDER},
{"&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 *)view_plugin_cb, (void*)(-1)},
{"&Visibility", FL_CTRL+FL_SHIFT+'v', (Fl_Callback *)visibility_cb, 0},
{"&Clipping Planes", FL_CTRL+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0},
{"&Manipulator", FL_CTRL+FL_SHIFT+'m', (Fl_Callback *)manip_cb, 0, FL_MENU_DIVIDER},
{"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_xyz1p_cb, (void*)"?", FL_MENU_DIVIDER},
{"&About Gmsh...", 0, (Fl_Callback *)help_about_cb, 0},
{0},
{0}
};
// 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)
#if defined(__APPLE__) && defined(HAVE_FLTK_1_1_5_OR_ABOVE)
// random changes in fltk are driving me nuts sometimes
#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 1) && (FL_PATCH_VERSION <= 6)
#undef FL_META
#define FL_META FL_CTRL
#endif
Fl_Menu_Item m_sys_menubar_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},
{"Merge...", FL_META+FL_SHIFT+'o', (Fl_Callback *)file_merge_cb, 0, FL_MENU_DIVIDER},
{"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},
{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 *)view_plugin_cb, (void*)(-1)},
{"Visibility", FL_META+FL_SHIFT+'v', (Fl_Callback *)visibility_cb, 0},
{"Clipping Planes", FL_META+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0},
{"Manipulator", FL_META+FL_SHIFT+'m', (Fl_Callback *)manip_cb, 0, FL_MENU_DIVIDER},
{"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},
{"Current Options", 0, (Fl_Callback *)status_xyz1p_cb, (void*)"?", FL_MENU_DIVIDER},
{"About Gmsh...", 0, (Fl_Callback *)help_about_cb, 0},
{0},
{0}
};
#endif
Fl_Menu_Item m_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}
};
// Definition of the dynamic contexts
Context_Item menu_geometry[] = {
{"0Geometry", NULL} ,
{"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} ,
{0}
};
Context_Item menu_geometry_elementary[] = {
{"0Geometry>Elementary", NULL} ,
{"Add", (Fl_Callback *)geometry_elementary_add_cb} ,
{"Delete", (Fl_Callback *)geometry_elementary_delete_cb} ,
{"Translate", (Fl_Callback *)geometry_elementary_translate_cb} ,
{"Rotate", (Fl_Callback *)geometry_elementary_rotate_cb} ,
{"Scale", (Fl_Callback *)geometry_elementary_scale_cb} ,
{"Symmetry", (Fl_Callback *)geometry_elementary_symmetry_cb} ,
{"Extrude", (Fl_Callback *)geometry_elementary_extrude_cb} ,
{"Coherence", (Fl_Callback *)geometry_elementary_coherence_cb} ,
{0}
};
Context_Item menu_geometry_elementary_add[] = {
{"0Geometry>Elementary>Add", NULL} ,
{"New", (Fl_Callback *)geometry_elementary_add_new_cb} ,
{"Translate", (Fl_Callback *)geometry_elementary_add_translate_cb} ,
{"Rotate", (Fl_Callback *)geometry_elementary_add_rotate_cb} ,
{"Scale", (Fl_Callback *)geometry_elementary_add_scale_cb} ,
{"Symmetry", (Fl_Callback *)geometry_elementary_add_symmetry_cb} ,
{0}
};
Context_Item menu_geometry_elementary_add_new[] = {
{"0Geometry>Elementary>Add>New", NULL} ,
{"Parameter", (Fl_Callback *)geometry_elementary_add_new_parameter_cb} ,
{"Point", (Fl_Callback *)geometry_elementary_add_new_point_cb} ,
{"Straight line", (Fl_Callback *)geometry_elementary_add_new_line_cb} ,
{"Spline", (Fl_Callback *)geometry_elementary_add_new_spline_cb} ,
{"B-Spline", (Fl_Callback *)geometry_elementary_add_new_bspline_cb} ,
{"Circle arc", (Fl_Callback *)geometry_elementary_add_new_circle_cb} ,
{"Ellipse arc", (Fl_Callback *)geometry_elementary_add_new_ellipse_cb} ,
{"Plane surface", (Fl_Callback *)geometry_elementary_add_new_planesurface_cb} ,
{"Ruled surface", (Fl_Callback *)geometry_elementary_add_new_ruledsurface_cb} ,
{"Volume", (Fl_Callback *)geometry_elementary_add_new_volume_cb} ,
{0}
};
Context_Item menu_geometry_elementary_add_translate[] = {
{"0Geometry>Elementary>Add>Translate", NULL} ,
{"Point", (Fl_Callback *)geometry_elementary_add_translate_point_cb} ,
{"Line", (Fl_Callback *)geometry_elementary_add_translate_line_cb} ,
{"Surface", (Fl_Callback *)geometry_elementary_add_translate_surface_cb} ,
{0}
};
Context_Item menu_geometry_elementary_add_rotate[] = {
{"0Geometry>Elementary>Add>Rotate", NULL} ,
{"Point", (Fl_Callback *)geometry_elementary_add_rotate_point_cb} ,
{"Line", (Fl_Callback *)geometry_elementary_add_rotate_line_cb} ,
{"Surface", (Fl_Callback *)geometry_elementary_add_rotate_surface_cb} ,
{0}
};
Context_Item menu_geometry_elementary_add_scale[] = {
{"0Geometry>Elementary>Add>Scale", NULL} ,
{"Point", (Fl_Callback *)geometry_elementary_add_scale_point_cb} ,
{"Line", (Fl_Callback *)geometry_elementary_add_scale_line_cb} ,
{"Surface", (Fl_Callback *)geometry_elementary_add_scale_surface_cb} ,
{0}
};
Context_Item menu_geometry_elementary_add_symmetry[] = {
{"0Geometry>Elementary>Add>Symmetry", NULL} ,
{"Point", (Fl_Callback *)geometry_elementary_add_symmetry_point_cb} ,
{"Line", (Fl_Callback *)geometry_elementary_add_symmetry_line_cb} ,
{"Surface", (Fl_Callback *)geometry_elementary_add_symmetry_surface_cb} ,
{0}
};
Context_Item menu_geometry_elementary_translate[] = {
{"0Geometry>Elementary>Translate", NULL} ,
{"Point", (Fl_Callback *)geometry_elementary_translate_point_cb} ,
{"Line", (Fl_Callback *)geometry_elementary_translate_line_cb} ,
{"Surface", (Fl_Callback *)geometry_elementary_translate_surface_cb} ,
{0}
};
Context_Item menu_geometry_elementary_rotate[] = {
{"0Geometry>Elementary>Rotate", NULL} ,
{"Point", (Fl_Callback *)geometry_elementary_rotate_point_cb} ,
{"Line", (Fl_Callback *)geometry_elementary_rotate_line_cb} ,
{"Surface", (Fl_Callback *)geometry_elementary_rotate_surface_cb} ,
{0}
};
Context_Item menu_geometry_elementary_scale[] = {
{"0Geometry>Elementary>Scale", NULL} ,
{"Point", (Fl_Callback *)geometry_elementary_scale_point_cb} ,
{"Line", (Fl_Callback *)geometry_elementary_scale_line_cb} ,
{"Surface", (Fl_Callback *)geometry_elementary_scale_surface_cb} ,
{0}
};
Context_Item menu_geometry_elementary_symmetry[] = {
{"0Geometry>Elementary>Symmetry", NULL} ,
{"Point", (Fl_Callback *)geometry_elementary_symmetry_point_cb} ,
{"Line", (Fl_Callback *)geometry_elementary_symmetry_line_cb} ,
{"Surface", (Fl_Callback *)geometry_elementary_symmetry_surface_cb} ,
{0}
};
Context_Item menu_geometry_elementary_extrude[] = {
{"0Geometry>Elementary>Extrude", NULL} ,
{"Translate", (Fl_Callback *)geometry_elementary_extrude_translate_cb} ,
{"Rotate", (Fl_Callback *)geometry_elementary_extrude_rotate_cb} ,
{0}
};
Context_Item menu_geometry_elementary_extrude_translate[] = {
{"0Geometry>Elementary>Extrude>Translate", NULL} ,
{"Point", (Fl_Callback *)geometry_elementary_extrude_translate_point_cb} ,
{"Line", (Fl_Callback *)geometry_elementary_extrude_translate_line_cb} ,
{"Surface", (Fl_Callback *)geometry_elementary_extrude_translate_surface_cb} ,
{0}
};
Context_Item menu_geometry_elementary_extrude_rotate[] = {
{"0Geometry>Elementary>Extrude>Rotate", NULL} ,
{"Point", (Fl_Callback *)geometry_elementary_extrude_rotate_point_cb} ,
{"Line", (Fl_Callback *)geometry_elementary_extrude_rotate_line_cb} ,
{"Surface", (Fl_Callback *)geometry_elementary_extrude_rotate_surface_cb} ,
{0}
};
Context_Item menu_geometry_elementary_delete[] = {
{"0Geometry>Elementary>Delete", NULL} ,
{"Point", (Fl_Callback *)geometry_elementary_delete_point_cb} ,
{"Line", (Fl_Callback *)geometry_elementary_delete_line_cb} ,
{"Surface", (Fl_Callback *)geometry_elementary_delete_surface_cb} ,
{0}
};
Context_Item menu_geometry_physical[] = {
{"0Geometry>Physical", NULL} ,
{"Add", (Fl_Callback *)geometry_physical_add_cb} ,
{0}
};
Context_Item menu_geometry_physical_add[] = {
{"0Geometry>Physical>Add", NULL} ,
{"Point", (Fl_Callback *)geometry_physical_add_point_cb } ,
{"Line", (Fl_Callback *)geometry_physical_add_line_cb } ,
{"Surface", (Fl_Callback *)geometry_physical_add_surface_cb } ,
{"Volume", (Fl_Callback *)geometry_physical_add_volume_cb } ,
{0}
};
Context_Item menu_mesh[] = {
{"1Mesh", NULL} ,
{"Define", (Fl_Callback *)mesh_define_cb} ,
{"Inspect", (Fl_Callback *)mesh_inspect_cb} ,
{"Edit", (Fl_Callback *)mesh_edit_cb} ,
{"1D", (Fl_Callback *)mesh_1d_cb} ,
{"2D", (Fl_Callback *)mesh_2d_cb} ,
{"3D", (Fl_Callback *)mesh_3d_cb} ,
{"First order", (Fl_Callback *)mesh_degree_cb, (void*)1 } ,
{"Second order", (Fl_Callback *)mesh_degree_cb, (void*)2 } ,
#if defined(HAVE_NETGEN)
{"Optimize quality", (Fl_Callback *)mesh_optimize_cb} ,
#endif
{"Save", (Fl_Callback *)mesh_save_cb} ,
{0}
};
Context_Item menu_mesh_edit[] = {
{"1Mesh>Edit", NULL} ,
{"Delete", (Fl_Callback *)mesh_delete_cb} ,
//{"Update edges", (Fl_Callback *)mesh_update_edges_cb} ,
{"Reparameterize", (Fl_Callback *)mesh_parameterize_cb} ,
//{"Remesh 2D", (Fl_Callback *)mesh_remesh_cb} ,
{0}
};
Context_Item menu_mesh_delete[] = {
{"1Mesh>Edit>Delete", NULL} ,
{"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"} ,
{0}
};
Context_Item menu_mesh_define[] = {
{"1Mesh>Define", NULL} ,
{"Characteristic length", (Fl_Callback *)mesh_define_length_cb } ,
{"Recombine", (Fl_Callback *)mesh_define_recombine_cb } ,
{"Transfinite", (Fl_Callback *)mesh_define_transfinite_cb } ,
{0}
};
Context_Item menu_mesh_define_transfinite[] = {
{"1Mesh>Define>Transfinite", NULL} ,
{"Line", (Fl_Callback *)mesh_define_transfinite_line_cb} ,
{"Surface", (Fl_Callback *)mesh_define_transfinite_surface_cb} ,
{"Volume", (Fl_Callback *)mesh_define_transfinite_volume_cb} ,
{0}
};
// FIXME: should create MAXSOLVERS items...
Context_Item menu_solver[] = {
{"2Solver", NULL} ,
{"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} ,
{0}
};
Context_Item menu_post[] = {
{"3Post-processing", NULL} ,
{0}
};
// some other reusable menus
static Fl_Menu_Item menu_point_display[] = {
{"Color dot", 0, 0, 0},
{"3D sphere", 0, 0, 0},
{0}
};
static Fl_Menu_Item menu_line_display[] = {
{"Color segment", 0, 0, 0},
{"3D cylinder", 0, 0, 0},
{0}
};
static Fl_Menu_Item menu_axes_mode[] = {
{"None", 0, 0, 0},
{"Simple axes", 0, 0, 0},
{"Box", 0, 0, 0},
{"Full grid", 0, 0, 0},
{"Open grid", 0, 0, 0},
{"Ruler", 0, 0, 0},
{0}
};
#define NUM_FONTS 14
Fl_Menu_Item menu_font_names[] = {
{"Times-Roman", 0, 0, (void*)FL_TIMES},
{"Times-Bold", 0, 0, (void*)FL_TIMES_BOLD},
{"Times-Italic", 0, 0, (void*)FL_TIMES_ITALIC},
{"Times-BoldItalic", 0, 0, (void*)FL_TIMES_BOLD_ITALIC},
{"Helvetica", 0, 0, (void*)FL_HELVETICA},
{"Helvetica-Bold", 0, 0, (void*)FL_HELVETICA_BOLD},
{"Helvetica-Oblique", 0, 0, (void*)FL_HELVETICA_ITALIC},
{"Helvetica-BoldOblique", 0, 0, (void*)FL_HELVETICA_BOLD_ITALIC},
{"Courier", 0, 0, (void*)FL_COURIER},
{"Courier-Bold", 0, 0, (void*)FL_COURIER_BOLD},
{"Courier-Oblique", 0, 0, (void*)FL_COURIER_ITALIC},
{"Courier-BoldOblique", 0, 0, (void*)FL_COURIER_BOLD_ITALIC},
{"Symbol", 0, 0, (void*)FL_SYMBOL},
{"ZapfDingbats", 0, 0, (void*)FL_ZAPF_DINGBATS},
{0}
};
int GetFontIndex(char *fontname)
{
if(fontname){
for(int i = 0; i < NUM_FONTS; i++)
if(!strcmp(menu_font_names[i].label(), fontname))
return i;
}
Msg(GERROR, "Unknown font \"%s\" (using \"Helvetica\" instead)", fontname);
Msg(INFO, "Available fonts:");
for(int i = 0; i < NUM_FONTS; i++)
Msg(INFO, " \"%s\"", menu_font_names[i].label());
return 4;
}
int GetFontEnum(int index)
{
if(index >= 0 && index < NUM_FONTS)
return (long)menu_font_names[index].user_data();
return FL_HELVETICA;
}
char *GetFontName(int index)
{
if(index >= 0 && index < NUM_FONTS)
return (char*)menu_font_names[index].label();
return "Helvetica";
}
int GetFontAlign(char *alignstr)
{
if(alignstr){
if(!strcmp(alignstr, "BottomLeft") || !strcmp(alignstr, "Left") ||
!strcmp(alignstr, "left"))
return 0;
else if(!strcmp(alignstr, "BottomCenter") || !strcmp(alignstr, "Center") ||
!strcmp(alignstr, "center"))
return 1;
else if(!strcmp(alignstr, "BottomRight") || !strcmp(alignstr, "Right") ||
!strcmp(alignstr, "right"))
return 2;
else if(!strcmp(alignstr, "TopLeft"))
return 3;
else if(!strcmp(alignstr, "TopCenter"))
return 4;
else if(!strcmp(alignstr, "TopRight"))
return 5;
else if(!strcmp(alignstr, "CenterLeft"))
return 6;
else if(!strcmp(alignstr, "CenterCenter"))
return 7;
else if(!strcmp(alignstr, "CenterRight"))
return 8;
}
Msg(GERROR, "Unknown font alignment \"%s\" (using \"Left\" instead)", alignstr);
Msg(INFO, "Available font alignments:");
Msg(INFO, " \"Left\" (or \"BottomLeft\")");
Msg(INFO, " \"Center\" (or \"BottomCenter\")");
Msg(INFO, " \"Right\" (or \"BottomRight\")");
Msg(INFO, " \"TopLeft\"");
Msg(INFO, " \"TopCenter\"");
Msg(INFO, " \"TopRight\"");
Msg(INFO, " \"CenterLeft\"");
Msg(INFO, " \"CenterCenter\"");
Msg(INFO, " \"CenterRight\"");
return 0;
}
// Definition of global shortcuts
int GUI::global_shortcuts(int event)
{
int i, j;
// we only handle shortcuts here
if(event != FL_SHORTCUT)
return 0;
if(Fl::test_shortcut('0')) {
geometry_reload_cb(0, 0);
mod_geometry_cb(0, 0);
return 1;
}
else if(Fl::test_shortcut('1') || Fl::test_shortcut(FL_F + 1)) {
mesh_1d_cb(0, 0);
mod_mesh_cb(0, 0);
return 1;
}
else if(Fl::test_shortcut('2') || Fl::test_shortcut(FL_F + 2)) {
mesh_2d_cb(0, 0);
mod_mesh_cb(0, 0);
return 1;
}
else if(Fl::test_shortcut('3') || Fl::test_shortcut(FL_F + 3)) {
mesh_3d_cb(0, 0);
mod_mesh_cb(0, 0);
return 1;
}
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...
file_quit_cb(0, 0);
return 1;
}
else if(Fl::test_shortcut('g')) {
mod_geometry_cb(0, 0);
return 1;
}
else if(Fl::test_shortcut('m')) {
mod_mesh_cb(0, 0);
return 1;
}
else if(Fl::test_shortcut('s')) {
mod_solver_cb(0, 0);
return 1;
}
else if(Fl::test_shortcut('p')) {
mod_post_cb(0, 0);
return 1;
}
else if(Fl::test_shortcut('<')) {
mod_back_cb(0, 0);
return 1;
}
else if(Fl::test_shortcut('>')) {
mod_forward_cb(0, 0);
return 1;
}
else if(Fl::test_shortcut('e')) {
end_selection = 1;
return 0; // trick: do as if we didn't use it
}
else if(Fl::test_shortcut('u')) {
undo_selection = 1;
return 0; // trick: do as if we didn't use it
}
else if(Fl::test_shortcut('q')) {
quit_selection = 1;
return 0; // trick: do as if we didn't use it
}
else if(Fl::test_shortcut('-')) {
invert_selection = 1;
return 0; // trick: do as if we didn't use it
}
else if(Fl::test_shortcut(FL_Escape) ||
Fl::test_shortcut(FL_META + FL_Escape) ||
Fl::test_shortcut(FL_SHIFT + FL_Escape) ||
Fl::test_shortcut(FL_CTRL + FL_Escape) ||
Fl::test_shortcut(FL_ALT + FL_Escape)) {
if(g_opengl_window->LassoMode){
g_opengl_window->LassoMode = false;
redraw_opengl();
}
else{
status_xyz1p_cb(0, (void *)"S");
}
return 1;
}
else if(Fl::test_shortcut(FL_SHIFT + 'a')) {
window_cb(0, (void*)"front");
return 1;
}
else if(Fl::test_shortcut(FL_SHIFT + 'o')) {
general_options_cb(0, 0);
return 1;
}
else if(Fl::test_shortcut(FL_SHIFT + 'g')) {
geometry_options_cb(0, 0);
return 1;
}
else if(Fl::test_shortcut(FL_SHIFT + 'm')) {
mesh_options_cb(0, 0);
return 1;
}
else if(Fl::test_shortcut(FL_SHIFT + 's')) {
solver_options_cb(0, 0);
return 1;
}
else if(Fl::test_shortcut(FL_SHIFT + 'p')) {
post_options_cb(0, 0);
return 1;
}
else if(Fl::test_shortcut(FL_SHIFT + 'w')) {
if(List_Nbr(CTX.post.list))
if(view_number >= 0 && view_number < List_Nbr(CTX.post.list))
create_view_options_window(view_number);
else
create_view_options_window(0);
return 1;
}
else if(Fl::test_shortcut(FL_SHIFT + 'u')) {
if(List_Nbr(CTX.post.list))
if(view_number >= 0 && view_number < List_Nbr(CTX.post.list))
create_plugin_window(view_number);
else
create_plugin_window(0);
return 1;
}
else if(Fl::test_shortcut(FL_ALT + 'f')) {
opt_general_fast_redraw(0, GMSH_SET | GMSH_GUI,
!opt_general_fast_redraw(0, GMSH_GET, 0));
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + 'b')) {
opt_general_draw_bounding_box(0, GMSH_SET | GMSH_GUI,
!opt_general_draw_bounding_box(0, GMSH_GET, 0));
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + 'i')) {
for(i = 0; i < List_Nbr(CTX.post.list); i++)
if(opt_view_visible(i, GMSH_GET, 0))
opt_view_show_scale(i, GMSH_SET | GMSH_GUI,
!opt_view_show_scale(i, GMSH_GET, 0));
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + 'c')) {
opt_general_color_scheme(0, GMSH_SET | GMSH_GUI,
opt_general_color_scheme(0, GMSH_GET, 0) + 1);
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + 'w')) {
opt_geometry_light(0, GMSH_SET | GMSH_GUI,
!opt_geometry_light(0, GMSH_GET, 0));
opt_mesh_light(0, GMSH_SET | GMSH_GUI,
!opt_mesh_light(0, GMSH_GET, 0));
for(i = 0; i < List_Nbr(CTX.post.list); i++)
if(opt_view_visible(i, GMSH_GET, 0))
opt_view_light(i, GMSH_SET | GMSH_GUI,
!opt_view_light(i, GMSH_GET, 0));
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + FL_SHIFT + 'w')) {
opt_mesh_reverse_all_normals(0, GMSH_SET | GMSH_GUI,
!opt_mesh_reverse_all_normals(0, GMSH_GET, 0));
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + 'x') ||
Fl::test_shortcut(FL_ALT + FL_SHIFT + 'x')) {
status_xyz1p_cb(0, (void *)"x");
return 1;
}
else if(Fl::test_shortcut(FL_ALT + 'y') ||
Fl::test_shortcut(FL_ALT + FL_SHIFT + 'y')) {
status_xyz1p_cb(0, (void *)"y");
return 1;
}
else if(Fl::test_shortcut(FL_ALT + 'z') ||
Fl::test_shortcut(FL_ALT + FL_SHIFT + 'z')) {
status_xyz1p_cb(0, (void *)"z");
return 1;
}
else if(Fl::test_shortcut(FL_ALT + 'o') ||
Fl::test_shortcut(FL_ALT + FL_SHIFT + 'o')) {
status_xyz1p_cb(0, (void *)"p");
return 1;
}
else if(Fl::test_shortcut(FL_ALT + 'a')) {
opt_general_axes(0, GMSH_SET | GMSH_GUI,
opt_general_axes(0, GMSH_GET, 0) + 1);
for(i = 0; i < List_Nbr(CTX.post.list); i++)
if(opt_view_visible(i, GMSH_GET, 0))
opt_view_axes(i, GMSH_SET | GMSH_GUI, opt_view_axes(i, GMSH_GET, 0)+1);
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + FL_SHIFT + 'a')) {
opt_general_small_axes(0, GMSH_SET | GMSH_GUI,
!opt_general_small_axes(0, GMSH_GET, 0));
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + 'p')) {
opt_geometry_points(0, GMSH_SET | GMSH_GUI,
!opt_geometry_points(0, GMSH_GET, 0));
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + 'l')) {
opt_geometry_lines(0, GMSH_SET | GMSH_GUI,
!opt_geometry_lines(0, GMSH_GET, 0));
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + 's')) {
opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI,
!opt_geometry_surfaces(0, GMSH_GET, 0));
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + 'v')) {
opt_geometry_volumes(0, GMSH_SET | GMSH_GUI,
!opt_geometry_volumes(0, GMSH_GET, 0));
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + FL_SHIFT + 'p')) {
opt_mesh_points(0, GMSH_SET | GMSH_GUI, !opt_mesh_points(0, GMSH_GET, 0));
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + FL_SHIFT + 'l')) {
opt_mesh_lines(0, GMSH_SET | GMSH_GUI,
!opt_mesh_lines(0, GMSH_GET, 0));
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + FL_SHIFT + 's')) {
opt_mesh_surfaces_edges(0, GMSH_SET | GMSH_GUI,
!opt_mesh_surfaces_edges(0, GMSH_GET, 0));
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + FL_SHIFT + 'v')) {
opt_mesh_volumes_edges(0, GMSH_SET | GMSH_GUI,
!opt_mesh_volumes_edges(0, GMSH_GET, 0));
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + 'd') ||
Fl::test_shortcut(FL_ALT + FL_SHIFT + 'd')) {
opt_mesh_surfaces_faces(0, GMSH_SET | GMSH_GUI,
!opt_mesh_surfaces_faces(0, GMSH_GET, 0));
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + FL_SHIFT + 'b')) {
opt_mesh_volumes_faces(0, GMSH_SET | GMSH_GUI,
!opt_mesh_volumes_faces(0, GMSH_GET, 0));
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + 'm')) {
int old = opt_mesh_points(0, GMSH_GET, 0) ||
opt_mesh_lines(0, GMSH_GET, 0) ||
opt_mesh_surfaces_edges(0, GMSH_GET, 0) ||
opt_mesh_surfaces_faces(0, GMSH_GET, 0);
opt_mesh_points(0, GMSH_SET | GMSH_GUI, !old);
opt_mesh_lines(0, GMSH_SET | GMSH_GUI, !old);
opt_mesh_surfaces_edges(0, GMSH_SET | GMSH_GUI, !old);
opt_mesh_surfaces_faces(0, GMSH_SET | GMSH_GUI, !old);
opt_mesh_volumes_edges(0, GMSH_SET | GMSH_GUI, !old);
opt_mesh_volumes_faces(0, GMSH_SET | GMSH_GUI, !old);
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + 't')) {
for(i = 0; i < List_Nbr(CTX.post.list); i++) {
if(opt_view_visible(i, GMSH_GET, 0)) {
j = (int)opt_view_intervals_type(i, GMSH_GET, 0);
opt_view_intervals_type(i, GMSH_SET | GMSH_GUI,
(j == DRAW_POST_ISO) ? DRAW_POST_DISCRETE :
(j == DRAW_POST_DISCRETE) ? DRAW_POST_CONTINUOUS :
DRAW_POST_ISO);
}
}
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + 'r')) {
for(i = 0; i < List_Nbr(CTX.post.list); i++) {
if(opt_view_visible(i, GMSH_GET, 0)) {
j = (int)opt_view_range_type(i, GMSH_GET, 0);
opt_view_range_type(i, GMSH_SET | GMSH_GUI,
(j == DRAW_POST_RANGE_DEFAULT) ? DRAW_POST_RANGE_PER_STEP :
(j == DRAW_POST_RANGE_PER_STEP) ? DRAW_POST_RANGE_CUSTOM :
DRAW_POST_RANGE_DEFAULT);
}
}
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + 'n')) {
for(i = 0; i < List_Nbr(CTX.post.list); i++)
if(opt_view_visible(i, GMSH_GET, 0))
opt_view_draw_strings(i, GMSH_SET | GMSH_GUI,
!opt_view_draw_strings(i, GMSH_GET, 0));
redraw_opengl();
return 1;
}
else if(Fl::test_shortcut(FL_ALT + 'h')) {
static int show = 0;
for(i = 0; i < List_Nbr(CTX.post.list); i++)
opt_view_visible(i, GMSH_SET | GMSH_GUI, show);
redraw_opengl();
show = !show;
return 1;
}
else if(arrow_shortcuts()) {
return 1;
}
return 0;
}
// Test the arrow shortcuts (this is not in the global_shortcuts)
// since it is used elsewhere (where we want to override widget
// navigation: necessary since FLTK>=1.1)
int GUI::arrow_shortcuts()
{
if(Fl::test_shortcut(FL_Left)) {
ManualPlay(1, -1);
return 1;
}
else if(Fl::test_shortcut(FL_Right)) {
ManualPlay(1, 1);
return 1;
}
else if(Fl::test_shortcut(FL_Up)) {
ManualPlay(0, -1);
return 1;
}
else if(Fl::test_shortcut(FL_Down)) {
ManualPlay(0, 1);
return 1;
}
return 0;
}
// The GUI constructor
GUI::GUI(int argc, char **argv)
{
// initialize static windows
m_window = NULL;
g_window = NULL;
opt_window = NULL;
plugin_window = NULL;
stat_window = NULL;
msg_window = NULL;
vis_window = NULL;
clip_window = NULL;
manip_window = NULL;
about_window = NULL;
context_geometry_window = NULL;
context_mesh_window = NULL;
// initialize on-screen message buffer
onscreen_buffer[0][0] = '\0';
onscreen_buffer[1][0] = '\0';
// initialize selection bits
selection = ENT_NONE;
try_selection = quit_selection = end_selection = 0;
undo_selection = invert_selection = 0;
for(int i = 0; i < 4; i++) try_selection_xywh[i] = 0;
// set X display
if(strlen(CTX.display))
Fl::display(CTX.display);
// add global shortcuts
Fl::add_handler(SetGlobalShortcut);
// store fontsize now: we don't want any subsequent change
// (e.g. when doing a 'restore options') to be taken into account
// in the dynamic GUI features (set_context, plugin, etc.)
fontsize = CTX.fontsize;
// set default font size
FL_NORMAL_SIZE = fontsize;
// handle themes and tooltip font size
if(strlen(CTX.gui_theme))
Fl::scheme(CTX.gui_theme);
Fl_Tooltip::size(fontsize);
// register image formats not in core fltk library (jpeg/png)
fl_register_images();
// load default system icons (for file browser)
Fl_File_Icon::load_system_icons();
// add callback to respond to the Mac Finder (when you click on a
// document)
#if defined(__APPLE__) && defined(HAVE_FLTK_1_1_5_OR_ABOVE)
fl_open_callback(OpenProjectMacFinder);
#endif
// All static 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
create_menu_window();
create_graphic_window();
#if defined(WIN32)
m_window->icon((char *)LoadImage(fl_display, MAKEINTRESOURCE(IDI_ICON),
IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR));
#elif defined(__APPLE__)
// Nothing to do here
#else
fl_open_display();
Pixmap p1 = XCreateBitmapFromData(fl_display, DefaultRootWindow(fl_display),
gmsh32x32_bits, gmsh32x32_width,
gmsh32x32_height);
Pixmap p2 = XCreateBitmapFromData(fl_display, DefaultRootWindow(fl_display),
gmsh32x32_bits, gmsh32x32_width,
gmsh32x32_height);
m_window->icon((char *)p1);
g_window->icon((char *)p2);
#endif
// we must show() m_window first (at least on Win32, since the icon
// is associated with m_window); and besides, it's probably better
// to have the initial focus on g_window so that we can directly
// process graphical shortcuts (e.g. for time step selection)
m_window->show(1, argv);
g_window->show(1, argv);
g_opengl_window->take_focus();
create_option_window();
create_plugin_window(0);
create_message_window();
create_statistics_window();
create_visibility_window();
create_clip_window();
create_manip_window();
create_about_window();
create_geometry_context_window(0);
create_mesh_context_window(0);
for(int i = 0; i < MAXSOLVERS; i++) {
solver[i].window = NULL;
create_solver_window(i);
}
call_for_solver_plugin(-1);
// Draw the scene
g_opengl_window->redraw();
}
// Run the GUI until no window is left
int GUI::run()
{
return Fl::run();
}
// Check (now) if any pending events and run them
void GUI::check()
{
Fl::check();
}
// Wait for any events and run them
void GUI::wait()
{
Fl::wait();
}
void GUI::wait(double time)
{
Fl::wait(time);
}
// Create the menu window
void GUI::create_menu_window()
{
int y;
if(m_window) {
m_window->show();
return;
}
int width = 14 * fontsize;
// this is the initial height: no dynamic button is shown!
#if defined(__APPLE__) && defined(HAVE_FLTK_1_1_5_OR_ABOVE)
if(CTX.system_menu_bar){
MH = BH + 6; // the menu bar is not in the application!
}
else{
#endif
MH = BH + BH + 6;
#if defined(__APPLE__) && defined(HAVE_FLTK_1_1_5_OR_ABOVE)
}
#endif
m_window = new Main_Window(width, MH + NB_BUTT_SCROLL * BH, "Gmsh");
m_window->box(GMSH_WINDOW_BOX);
m_window->callback(file_quit_cb);
#if defined(__APPLE__) && defined(HAVE_FLTK_1_1_5_OR_ABOVE)
if(CTX.system_menu_bar){
// 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)
m_sys_menu_bar = new Fl_Sys_Menu_Bar(1, 1, 1, 1);
m_sys_menu_bar->menu(m_sys_menubar_table);
m_sys_menu_bar->global();
Fl_Box *o = new Fl_Box(0, 0, width, BH + 6);
o->box(FL_UP_BOX);
y = 3;
}
else{
#endif
m_menu_bar = new Fl_Menu_Bar(0, 0, width, BH);
m_menu_bar->menu(m_menubar_table);
m_menu_bar->box(FL_UP_BOX);
m_menu_bar->global();
Fl_Box *o = new Fl_Box(0, BH, width, BH + 6);
o->box(FL_UP_BOX);
y = BH + 3;
#if defined(__APPLE__) && defined(HAVE_FLTK_1_1_5_OR_ABOVE)
}
#endif
m_navig_butt[0] = new Fl_Button(1, y, 18, BH / 2, "@#-1<");
m_navig_butt[0]->labeltype(FL_SYMBOL_LABEL);
m_navig_butt[0]->box(FL_FLAT_BOX);
m_navig_butt[0]->selection_color(FL_WHITE);
m_navig_butt[0]->callback(mod_back_cb);
m_navig_butt[0]->tooltip("Go back one in the menu history (<)");
m_navig_butt[1] = new Fl_Button(1, y + BH / 2, 18, BH / 2, "@#-1>");
m_navig_butt[1]->labeltype(FL_SYMBOL_LABEL);
m_navig_butt[1]->box(FL_FLAT_BOX);
m_navig_butt[1]->selection_color(FL_WHITE);
m_navig_butt[1]->callback(mod_forward_cb);
m_navig_butt[1]->tooltip("Go forward one in the menu history (>)");
m_module_butt = new Fl_Choice(19, y, width - 24, BH);
m_module_butt->menu(m_module_table);
m_module_butt->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):
m_module_butt->when(FL_WHEN_RELEASE_ALWAYS);
// create an empty scroll area that will get populated dynamically
// in set_context()
m_scroll = new Fl_Scroll(0, MH, width, NB_BUTT_SCROLL * BH);
m_scroll->type(Fl_Scroll::VERTICAL);
m_scroll->end();
m_window->size(width, MH);
m_window->position(CTX.position[0], CTX.position[1]);
// force always on top
//m_window->set_non_modal();
m_window->end();
}
// Dynamically set the context
void GUI::set_context(Context_Item * menu_asked, int flag)
{
static int nb_back = 0, nb_forward = 0, init_context = 0;
static Context_Item *menu_history[NB_HISTORY_MAX];
Context_Item *menu;
if(!init_context) {
init_context = 1;
for(int i = 0; i < NB_HISTORY_MAX; i++) {
menu_history[i] = NULL;
}
}
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 {
menu = menu_asked;
if(!nb_back || menu_history[nb_back - 1] != menu) {
menu_history[nb_back++] = menu;
}
nb_forward = 0;
}
if(menu[0].label[0] == '0'){
m_module_butt->value(0);
}
else if(menu[0].label[0] == '1'){
m_module_butt->value(1);
}
else if(menu[0].label[0] == '2'){
m_module_butt->value(2);
menu[1].label = opt_solver_name0(0, GMSH_GET, 0);
menu[2].label = opt_solver_name1(0, GMSH_GET, 0);
menu[3].label = opt_solver_name2(0, GMSH_GET, 0);
menu[4].label = opt_solver_name3(0, GMSH_GET, 0);
menu[5].label = opt_solver_name4(0, GMSH_GET, 0);
for(int i = 0; i < MAXSOLVERS; i++) {
if(!strlen(menu[i + 1].label))
menu[i + 1].label = NULL;
}
}
else if(menu[0].label[0] == '3'){
m_module_butt->value(3);
}
else {
Msg(WARNING, "Something is wrong in your dynamic context definition");
return;
}
Msg(STATUS1N, menu[0].label + 1);
// Remove all the children (m_push*, m_toggle*, m_pop*). FLTK <=
// 1.1.4 should be OK with this. FLTK 1.1.5 may crash as it may
// access a widget's data after its callback is executed (we call
// set_context in the button callbacks!). FLTK 1.1.6 introduced a
// fix (Fl::delete_widget) to delay the deletion until the next
// Fl::wait call. In any case, we cannot use m_scroll->clear()
// (broken in < 1.1.5, potential crasher in >= 1.1.5).
for(unsigned int i = 0; i < m_push_butt.size(); i++){
m_scroll->remove(m_push_butt[i]);
#if defined(HAVE_FLTK_1_1_6_OR_ABOVE)
Fl::delete_widget(m_push_butt[i]);
#else
delete m_push_butt[i];
#endif
}
for(unsigned int i = 0; i < m_toggle_butt.size(); i++){
m_scroll->remove(m_toggle_butt[i]);
#if defined(HAVE_FLTK_1_1_6_OR_ABOVE)
Fl::delete_widget(m_toggle_butt[i]);
#else
delete m_toggle_butt[i];
#endif
}
for(unsigned int i = 0; i < m_toggle2_butt.size(); i++){
m_scroll->remove(m_toggle2_butt[i]);
#if defined(HAVE_FLTK_1_1_6_OR_ABOVE)
Fl::delete_widget(m_toggle2_butt[i]);
#else
delete m_toggle2_butt[i];
#endif
}
for(unsigned int i = 0; i < m_popup_butt.size(); i++){
m_scroll->remove(m_popup_butt[i]);
#if defined(HAVE_FLTK_1_1_6_OR_ABOVE)
Fl::delete_widget(m_popup_butt[i]);
#else
delete m_popup_butt[i];
#endif
}
for(unsigned int i = 0; i < m_popup2_butt.size(); i++){
m_scroll->remove(m_popup2_butt[i]);
#if defined(HAVE_FLTK_1_1_6_OR_ABOVE)
Fl::delete_widget(m_popup2_butt[i]);
#else
delete m_popup2_butt[i];
#endif
}
// reset the vectors
m_push_butt.clear();
m_toggle_butt.clear();
m_toggle2_butt.clear();
m_popup_butt.clear();
m_popup2_butt.clear();
for(unsigned int i = 0; i < m_pop_label.size(); i++)
delete [] m_pop_label[i];
m_pop_label.clear();
int width = m_window->w();
int popw = 4 * fontsize + 3;
// construct the dynamic menu
int nb = 0;
if(m_module_butt->value() == 3){ // post-processing context
for(nb = 0; nb < List_Nbr(CTX.post.list); nb++) {
Post_View *v = *(Post_View **) List_Pointer(CTX.post.list, nb);
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(v->Visible);
b1->label(v->Name);
b1->tooltip(v->FileName);
char *tmp = new char[32];
sprintf(tmp, "[%d]@#-1>", nb);
Fl_Button *b2 = new Fl_Button(width - popw, MH + nb * BH, popw, BH, tmp);
m_pop_label.push_back(tmp);
b2->align(FL_ALIGN_RIGHT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
b2->tooltip("Show view option menu (Shift+w)");
Popup_Button *p[2];
p[0] = new Popup_Button(width - popw, MH + nb * BH, popw, BH);
p[0]->type(Fl_Menu_Button::POPUP123);
p[1] = new Popup_Button(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", 0,
(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_visible_cb, (void *)nb, 0);
p[j]->add("Remove/Invisible Views", 0,
(Fl_Callback *) view_remove_invisible_cb, (void *)nb, 0);
p[j]->add("Remove/Empty Views", 0,
(Fl_Callback *) view_remove_empty_cb, (void *)nb, 0);
p[j]->add("Remove/All Views", 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 *)0, 0);
p[j]->add("Set Visibility/Invert", 0,
(Fl_Callback *) view_all_visible_cb, (void *)-1, 0);
p[j]->add("Save As/Parsed View...", 0,
(Fl_Callback *) view_save_parsed_cb, (void *)nb, 0);
p[j]->add("Save As/ASCII View...", 0,
(Fl_Callback *) view_save_ascii_cb, (void *)nb, 0);
p[j]->add("Save As/Binary View...", 0,
(Fl_Callback *) view_save_binary_cb, (void *)nb, 0);
p[j]->add("Save As/STL Triangulation...", 0,
(Fl_Callback *) view_save_stl_cb, (void *)nb, 0);
p[j]->add("Save As/Text...", 0,
(Fl_Callback *) view_save_txt_cb, (void *)nb, 0);
p[j]->add("Save As/Mesh...", 0,
(Fl_Callback *) view_save_msh_cb, (void *)nb, 0);
p[j]->add("Apply As Background Mesh", 0,
(Fl_Callback *) view_applybgmesh_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 *) view_plugin_cb, (void *)nb, 0);
}
m_toggle_butt.push_back(b1);
m_toggle2_butt.push_back(b2);
m_popup_butt.push_back(p[0]);
m_popup2_butt.push_back(p[1]);
m_scroll->add(b1);
m_scroll->add(b2);
m_scroll->add(p[0]);
m_scroll->add(p[1]);
}
}
else{ // geometry, mesh and solver contexts
while(menu[nb + 1].label) {
Fl_Button *b = new Fl_Button(0, MH + nb * BH, width, BH);
b->label(menu[nb + 1].label);
b->callback(menu[nb + 1].callback, menu[nb + 1].arg);
m_push_butt.push_back(b);
m_scroll->add(b);
nb++;
}
}
m_scroll->redraw();
if(nb <= NB_BUTT_SCROLL)
m_window->size(width, MH + nb * BH);
else
m_window->size(width, MH + NB_BUTT_SCROLL * BH);
}
int GUI::get_context()
{
return m_module_butt->value();
}
// Create the graphic window
void GUI::create_graphic_window()
{
if(g_window) {
g_window->show();
return;
}
int sh = 2 * fontsize - 4; // status bar height
int sw = fontsize + 4; // status button width
int width = CTX.viewport[2] - CTX.viewport[0];
int glheight = CTX.viewport[3] - CTX.viewport[1];
int height = glheight + sh;
g_window = new Main_Window(width, height);
g_window->callback(file_quit_cb);
// bottom button bar
Fl_Box *bottom = new Fl_Box(0, glheight, width, sh);
bottom->box(FL_FLAT_BOX);
int x = 2;
int sht = sh - 4; // leave a 2 pixel border at the bottom
g_status_butt[0] = new Fl_Button(x, glheight + 2, sw, sht, "X");
x += sw;
g_status_butt[0]->callback(status_xyz1p_cb, (void *)"x");
g_status_butt[0]->tooltip("Set +X or -X view (Alt+x or Alt+Shift+x)");
g_status_butt[1] = new Fl_Button(x, glheight + 2, sw, sht, "Y");
x += sw;
g_status_butt[1]->callback(status_xyz1p_cb, (void *)"y");
g_status_butt[1]->tooltip("Set +Y or -Y view (Alt+y or Alt+Shift+y)");
g_status_butt[2] = new Fl_Button(x, glheight + 2, sw, sht, "Z");
x += sw;
g_status_butt[2]->callback(status_xyz1p_cb, (void *)"z");
g_status_butt[2]->tooltip("Set +Z or -Z view (Alt+z or Alt+Shift+z)");
g_status_butt[4] = new Fl_Button(x, glheight + 2, sw, sht);
x += sw;
g_status_butt[4]->callback(status_xyz1p_cb, (void *)"r");
g_status_butt[4]->tooltip("Rotate +90 or -90 degrees");
rotate_bmp = new Fl_Bitmap(rotate_bits, rotate_width, rotate_height);
rotate_bmp->label(g_status_butt[4]);
g_status_butt[3] = new Fl_Button(x, glheight + 2, 2 * fontsize, sht, "1:1");
x += 2 * fontsize;
g_status_butt[3]->callback(status_xyz1p_cb, (void *)"1:1");
g_status_butt[3]->tooltip("Set unit scale");
g_status_butt[8] = new Fl_Button(x, glheight + 2, sw, sht);
x += sw;
g_status_butt[8]->callback(status_xyz1p_cb, (void *)"p");
g_status_butt[8]->tooltip("Toggle projection mode (Alt+o or Alt+Shift+o)");
ortho_bmp = new Fl_Bitmap(ortho_bits, ortho_width, ortho_height);
ortho_bmp->label(g_status_butt[8]);
g_status_butt[9] = new Fl_Button(x, glheight + 2, sw, sht, "S");
x += sw;
g_status_butt[9]->callback(status_xyz1p_cb, (void *)"S");
g_status_butt[9]->tooltip("Toggle mouse selection ON/OFF (Escape or Shift+Escape)");
g_status_butt[5] = new Fl_Button(x, glheight + 2, sw, sht, "?");
x += sw;
g_status_butt[5]->callback(status_xyz1p_cb, (void *)"?");
g_status_butt[5]->tooltip("Show current options");
g_status_butt[6] = new Fl_Button(x, glheight + 2, sw, sht);
x += sw;
g_status_butt[6]->callback(status_rewind_cb);
g_status_butt[6]->tooltip("Rewind animation");
rewind_bmp = new Fl_Bitmap(rewind_bits, rewind_width, rewind_height);
rewind_bmp->label(g_status_butt[6]);
g_status_butt[6]->deactivate();
g_status_butt[7] = new Fl_Button(x, glheight + 2, sw, sht);
x += sw;
g_status_butt[7]->callback(status_play_cb);
g_status_butt[7]->tooltip("Play/pause animation");
start_bmp = new Fl_Bitmap(start_bits, start_width, start_height);
start_bmp->label(g_status_butt[7]);
stop_bmp = new Fl_Bitmap(stop_bits, stop_width, stop_height);
g_status_butt[7]->deactivate();
for(int i = 0; i < 10; i++) {
g_status_butt[i]->box(FL_FLAT_BOX);
g_status_butt[i]->selection_color(FL_WHITE);
g_status_butt[i]->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
}
x += 2;
int wleft = (width - x) / 3 - 1;
int wright = (width - x) - (width - x) / 3 - 1;
g_status_label[0] = new Fl_Box(x, glheight + 2, wleft, sht);
g_status_label[1] = new Fl_Box(x + (width - x) / 3, glheight + 2, wright, sht);
for(int i = 0; i < 2; i++) {
g_status_label[i]->box(FL_THIN_DOWN_BOX);
g_status_label[i]->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
}
// dummy resizable box
Dummy_Box *resize_box = new Dummy_Box(x, 0, width - x, glheight);
g_window->resizable(resize_box);
// opengl window
g_opengl_window = new Opengl_Window(0, 0, width, glheight);
int mode = FL_RGB | FL_DEPTH | (CTX.db ? FL_DOUBLE : FL_SINGLE);
if(CTX.antialiasing) mode |= FL_MULTISAMPLE;
g_opengl_window->mode(mode);
g_opengl_window->end();
g_window->position(CTX.gl_position[0], CTX.gl_position[1]);
g_window->end();
}
// Set the size of the graphical window
void GUI::set_size(int new_w, int new_h)
{
g_window->size(new_w, new_h + g_window->h() - g_opengl_window->h());
}
// Set graphic window title
void GUI::set_title(char *str)
{
g_window->label(str);
}
// Set animation button
void GUI::set_anim_buttons(int mode)
{
if(mode) {
g_status_butt[7]->callback(status_play_cb);
start_bmp->label(g_status_butt[7]);
}
else {
g_status_butt[7]->callback(status_pause_cb);
stop_bmp->label(g_status_butt[7]);
}
}
void GUI::check_anim_buttons()
{
int i, play = 0;
if(CTX.post.anim_cycle) {
play = 1;
}
else {
for(i = 0; i < List_Nbr(CTX.post.list); i++) {
if((*(Post_View **) List_Pointer(CTX.post.list, i))->NbTimeStep > 1) {
play = 1;
break;
}
}
}
if(!play) {
g_status_butt[6]->deactivate();
g_status_butt[7]->deactivate();
}
else {
g_status_butt[6]->activate();
g_status_butt[7]->activate();
}
}
// Set the status messages
void GUI::set_status(char *msg, int num)
{
if(num == 0 || num == 1){
g_status_label[num]->label(msg);
g_status_label[num]->redraw();
}
else if(num == 3){
int n = strlen(msg);
int i = 0;
while(i < n)
if(msg[i++] == '\n') break;
strncpy(onscreen_buffer[0], msg, 255);
if(i < n)
strncpy(onscreen_buffer[1], &msg[i], 255);
else
onscreen_buffer[1][0] = '\0';
onscreen_buffer[0][i-1] = '\0';
redraw_opengl();
}
}
void GUI::add_multiline_in_browser(Fl_Browser * o, char *prefix, char *str)
{
int start = 0, len;
char *buff;
if(!str || !strlen(str) || !strcmp(str, "\n")) {
o->add(" ");
return;
}
for(unsigned int i = 0; i < strlen(str); i++) {
if(i == strlen(str) - 1 || str[i] == '\n') {
len = i - start + (str[i] == '\n' ? 0 : 1);
buff = new char[len + strlen(prefix) + 2];
strcpy(buff, prefix);
strncat(buff, &str[start], len);
buff[len + strlen(prefix)] = '\0';
o->add(buff);
start = i + 1;
}
}
}
// set the current drawing context
void GUI::make_opengl_current()
{
g_opengl_window->make_current();
}
// Draw the opengl window
void GUI::redraw_opengl()
{
g_opengl_window->make_current();
g_opengl_window->redraw();
check();
}
// Create the option window
void GUI::hide_all_option_groups()
{
gen_group->hide();
geo_group->hide();
mesh_group->hide();
solver_group->hide();
post_group->hide();
view_group->hide();
}
void GUI::create_general_options_window()
{
create_option_window();
hide_all_option_groups();
gen_group->show();
opt_browser->value(1);
opt_window->label("Options - General");
}
void GUI::create_geometry_options_window()
{
create_option_window();
hide_all_option_groups();
geo_group->show();
opt_browser->value(2);
opt_window->label("Options - Geometry");
}
void GUI::create_mesh_options_window()
{
create_option_window();
hide_all_option_groups();
mesh_group->show();
opt_browser->value(3);
opt_window->label("Options - Mesh");
}
void GUI::create_solver_options_window()
{
create_option_window();
hide_all_option_groups();
solver_group->show();
opt_browser->value(4);
opt_window->label("Options - Solver");
}
void GUI::create_post_options_window()
{
create_option_window();
hide_all_option_groups();
post_group->show();
opt_browser->value(5);
opt_window->label("Options - Post-processing");
}
void GUI::create_view_options_window(int num)
{
create_option_window();
hide_all_option_groups();
update_view_window(num);
view_group->show();
opt_browser->value(6 + num);
static char str[128];
sprintf(str, "Options - View [%d]", num);
opt_window->label(str);
}
void GUI::reset_option_browser()
{
char str[128];
int select = opt_browser->value();
opt_browser->clear();
opt_browser->add("General");
opt_browser->add("Geometry");
opt_browser->add("Mesh");
opt_browser->add("Solver");
opt_browser->add("Post-processing");
for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
sprintf(str, "View [%d]", i);
opt_browser->add(str);
}
int item = (select <= opt_browser->size()) ? select : opt_browser->size();
opt_browser->value(item);
hide_all_option_groups();
switch(item){
case 0: case 1: gen_group->show(); break;
case 2: geo_group->show(); break;
case 3: mesh_group->show(); break;
case 4: solver_group->show(); break;
case 5: post_group->show(); break;
default: update_view_window(item - 6); view_group->show(); break;
}
}
void GUI::reset_external_view_list()
{
char str[32];
view_choice[10]->clear();
view_choice[11]->clear();
view_choice[10]->add("Self");
view_choice[11]->add("Self");
for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
sprintf(str, "View [%d]", i);
view_choice[10]->add(str, 0, NULL);
view_choice[11]->add(str, 0, NULL);
}
if(view_number >= 0){
opt_view_external_view(view_number, GMSH_GUI, 0);
opt_view_gen_raise_view(view_number, GMSH_GUI, 0);
}
}
void GUI::create_option_window()
{
int width = 40 * fontsize;
int height = 13 * BH + 5 * WB;
int L = 8 * fontsize + WB;
if(opt_window) {
opt_window->show();
return;
}
opt_window = new Dialog_Window(width, height);
opt_window->box(GMSH_WINDOW_BOX);
// Buttons
{
Fl_Button *o = new Fl_Button(width - BB - WB, height - BH - WB, BB, BH, "Cancel");
o->callback(cancel_cb, (void *)opt_window);
}
{
Fl_Button *o = new Fl_Button((int)(width - 2.5 * BB - 2 * WB), height - BH - WB, (int)(1.5 * BB), BH, "Save as defaults");
o->callback(options_save_cb);
}
{
opt_redraw = new Fl_Return_Button((int)(width - 3.5 * BB - 3 * WB), height - BH - WB, BB, BH, "Redraw");
opt_redraw->callback(redraw_cb);
}
// Selection browser
opt_browser = new Fl_Hold_Browser(WB, WB, L - WB, height - 3 * WB - BH);
opt_browser->has_scrollbar(Fl_Browser_::VERTICAL);
opt_browser->add("General");
opt_browser->add("Geometry");
opt_browser->add("Mesh");
opt_browser->add("Solver");
opt_browser->add("Post-processing");
opt_browser->callback(options_browser_cb);
opt_browser->value(1);
opt_window->label("Options - General");
width -= L;
int BW = width - 4 * WB;
height -= WB + BH;
// General options
gen_group = new Fl_Group(L, 0, width, height, "General Options");
{
Fl_Tabs *o = new Fl_Tabs(L + WB, WB, width - 2 * WB, height - 2 * WB);
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "General");
gen_butt[10] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 1 * BH, BW, BH, "Enable expert mode");
gen_butt[10]->type(FL_TOGGLE_BUTTON);
gen_butt[10]->callback(general_options_ok_cb);
gen_butt[13] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 2 * BH, BW, BH, "Show tooltips");
gen_butt[13]->type(FL_TOGGLE_BUTTON);
gen_butt[13]->callback(general_options_ok_cb);
gen_butt[6] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW, BH, "Show bounding boxes");
gen_butt[6]->tooltip("(Alt+b)");
gen_butt[6]->type(FL_TOGGLE_BUTTON);
gen_butt[6]->callback(general_options_ok_cb);
gen_butt[2] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Draw simplified model during user interaction");
gen_butt[2]->tooltip("(Alt+f)");
gen_butt[2]->type(FL_TOGGLE_BUTTON);
gen_butt[2]->callback(general_options_ok_cb, (void*)"fast_redraw");
gen_butt[3] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 5 * BH, BW, BH, "Enable double buffering");
gen_butt[3]->type(FL_TOGGLE_BUTTON);
gen_butt[3]->callback(general_options_ok_cb);
gen_butt[12] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 6 * BH, BW, BH, "Enable antialiasing");
gen_butt[12]->type(FL_TOGGLE_BUTTON);
gen_butt[12]->callback(general_options_ok_cb);
gen_butt[5] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 7 * BH, BW, BH, "Use trackball rotation mode instead of Euler angles");
gen_butt[5]->type(FL_TOGGLE_BUTTON);
gen_butt[5]->callback(general_options_ok_cb);
gen_butt[15] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 8 * BH, BW, BH, "Rotate around pseudo center of mass");
gen_butt[15]->type(FL_TOGGLE_BUTTON);
gen_butt[15]->callback(general_options_ok_cb, (void*)"rotation_center");
gen_push_butt[0] = new Fl_Button(L + 2 * IW - 2 * WB, 2 * WB + 9 * BH, BB, BH, "Select");
gen_push_butt[0]->callback(general_options_rotation_center_select_cb);
gen_value[8] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 9 * BH, IW / 3, BH);
gen_value[8]->callback(general_options_ok_cb, (void*)"rotation_center_coord");
gen_value[9] = new Fl_Value_Input(L + 2 * WB + IW / 3, 2 * WB + 9 * BH, IW / 3, BH);
gen_value[9]->callback(general_options_ok_cb, (void*)"rotation_center_coord");
gen_value[10] = new Fl_Value_Input(L + 2 * WB + 2 * IW / 3, 2 * WB + 9 * BH, IW / 3, BH, "Rotation center");
gen_value[10]->align(FL_ALIGN_RIGHT);
gen_value[10]->callback(general_options_ok_cb, (void*)"rotation_center_coord");
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Axes");
gen_choice[4] = new Fl_Choice(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Axes mode");
gen_choice[4]->menu(menu_axes_mode);
gen_choice[4]->align(FL_ALIGN_RIGHT);
gen_choice[4]->tooltip("(Alt+a)");
gen_choice[4]->callback(general_options_ok_cb, (void*)"general_axes");
gen_value[17] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 2 * BH, IW/3, BH);
gen_value[17]->minimum(0.);
gen_value[17]->step(1);
gen_value[17]->maximum(100);
gen_value[17]->callback(general_options_ok_cb);
gen_value[18] = new Fl_Value_Input(L + 2 * WB + 1*IW/3, 2 * WB + 2 * BH, IW/3, BH);
gen_value[18]->minimum(0.);
gen_value[18]->step(1);
gen_value[18]->maximum(100);
gen_value[18]->callback(general_options_ok_cb);
gen_value[19] = new Fl_Value_Input(L + 2 * WB + 2*IW/3, 2 * WB + 2 * BH, IW/3, BH, "Axes tics");
gen_value[19]->minimum(0.);
gen_value[19]->step(1);
gen_value[19]->maximum(100);
gen_value[19]->align(FL_ALIGN_RIGHT);
gen_value[19]->callback(general_options_ok_cb);
gen_input[3] = new Fl_Input(L + 2 * WB, 2 * WB + 3 * BH, IW/3, BH);
gen_input[3]->callback(general_options_ok_cb);
gen_input[4] = new Fl_Input(L + 2 * WB + 1*IW/3, 2 * WB + 3 * BH, IW/3, BH);
gen_input[4]->callback(general_options_ok_cb);
gen_input[5] = new Fl_Input(L + 2 * WB + 2*IW/3, 2 * WB + 3 * BH, IW/3, BH, "Axes format");
gen_input[5]->align(FL_ALIGN_RIGHT);
gen_input[5]->callback(general_options_ok_cb);
gen_input[6] = new Fl_Input(L + 2 * WB, 2 * WB + 4 * BH, IW/3, BH);
gen_input[6]->callback(general_options_ok_cb);
gen_input[7] = new Fl_Input(L + 2 * WB + 1*IW/3, 2 * WB + 4 * BH, IW/3, BH);
gen_input[7]->callback(general_options_ok_cb);
gen_input[8] = new Fl_Input(L + 2 * WB + 2*IW/3, 2 * WB + 4 * BH, IW/3, BH, "Axes labels");
gen_input[8]->align(FL_ALIGN_RIGHT);
gen_input[8]->callback(general_options_ok_cb);
gen_butt[0] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 5 * BH, BW, BH, "Set position and size of axes automatically");
gen_butt[0]->type(FL_TOGGLE_BUTTON);
gen_butt[0]->callback(general_options_ok_cb, (void*)"general_axes_auto");
gen_value[20] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 6 * BH, IW / 3, BH);
gen_value[20]->callback(general_options_ok_cb);
gen_value[21] = new Fl_Value_Input(L + 2 * WB + IW / 3, 2 * WB + 6 * BH, IW / 3, BH);
gen_value[21]->callback(general_options_ok_cb);
gen_value[22] = new Fl_Value_Input(L + 2 * WB + 2 * IW / 3, 2 * WB + 6 * BH, IW / 3, BH, "Axes minimum");
gen_value[22]->align(FL_ALIGN_RIGHT);
gen_value[22]->callback(general_options_ok_cb);
gen_value[23] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 7 * BH, IW / 3, BH);
gen_value[23]->callback(general_options_ok_cb);
gen_value[24] = new Fl_Value_Input(L + 2 * WB + IW / 3, 2 * WB + 7 * BH, IW / 3, BH);
gen_value[24]->callback(general_options_ok_cb);
gen_value[25] = new Fl_Value_Input(L + 2 * WB + 2 * IW / 3, 2 * WB + 7 * BH, IW / 3, BH, "Axes maximum");
gen_value[25]->align(FL_ALIGN_RIGHT);
gen_value[25]->callback(general_options_ok_cb);
gen_butt[1] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 8 * BH, BW, BH, "Show small axes");
gen_butt[1]->tooltip("(Alt+Shift+a)");
gen_butt[1]->type(FL_TOGGLE_BUTTON);
gen_butt[1]->callback(general_options_ok_cb, (void*)"general_small_axes");
gen_value[26] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 9 * BH, IW / 2, BH);
gen_value[26]->minimum(-2000);
gen_value[26]->maximum(2000);
gen_value[26]->step(1);
gen_value[26]->callback(general_options_ok_cb);
gen_value[27] = new Fl_Value_Input(L + 2 * WB + IW / 2, 2 * WB + 9 * BH, IW / 2, BH, "Small axes position");
gen_value[27]->align(FL_ALIGN_RIGHT);
gen_value[27]->minimum(-2000);
gen_value[27]->maximum(2000);
gen_value[27]->step(1);
gen_value[27]->callback(general_options_ok_cb);
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Output");
gen_butt[7] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 1 * BH, BW, BH, "Print messages on terminal");
gen_butt[7]->type(FL_TOGGLE_BUTTON);
gen_butt[7]->callback(general_options_ok_cb);
gen_butt[8] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 2 * BH, BW, BH, "Save session information on exit");
gen_butt[8]->type(FL_TOGGLE_BUTTON);
gen_butt[8]->callback(general_options_ok_cb);
gen_butt[9] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW/2-WB, BH, "Save options on exit");
gen_butt[9]->type(FL_TOGGLE_BUTTON);
gen_butt[9]->callback(general_options_ok_cb);
Fl_Button *b0 = new Fl_Button(L + width / 2, 2 * WB + 3 * BH, 2 * BB, BH, "Restore default options");
b0->callback(options_restore_defaults_cb);
gen_butt[14] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Ask confirmation before overwriting files");
gen_butt[14]->type(FL_TOGGLE_BUTTON);
gen_butt[14]->callback(general_options_ok_cb);
gen_value[5] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Message verbosity");
gen_value[5]->minimum(0);
gen_value[5]->maximum(10);
gen_value[5]->step(1);
gen_value[5]->align(FL_ALIGN_RIGHT);
gen_value[5]->callback(general_options_ok_cb);
gen_input[0] = new Fl_Input(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Default file name");
gen_input[0]->align(FL_ALIGN_RIGHT);
gen_input[0]->callback(general_options_ok_cb);
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Helpers");
gen_input[1] = new Fl_Input(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Text editor command");
gen_input[1]->align(FL_ALIGN_RIGHT);
gen_input[1]->callback(general_options_ok_cb);
gen_input[2] = new Fl_Input(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Web browser command");
gen_input[2]->align(FL_ALIGN_RIGHT);
gen_input[2]->callback(general_options_ok_cb);
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Aspect");
o->hide();
static Fl_Menu_Item menu_projection[] = {
{"Orthographic", 0, 0, 0},
{"Perspective", 0, 0, 0},
{0}
};
gen_choice[2] = new Fl_Choice(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Projection mode");
gen_choice[2]->menu(menu_projection);
gen_choice[2]->align(FL_ALIGN_RIGHT);
gen_choice[2]->tooltip("(Alt+o)");
gen_choice[2]->callback(general_options_ok_cb);
gen_value[14] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Z-clipping planes distance factor");
gen_value[14]->minimum(0.1);
gen_value[14]->maximum(10.);
gen_value[14]->step(0.1);
gen_value[14]->align(FL_ALIGN_RIGHT);
gen_value[14]->callback(general_options_ok_cb);
gen_value[15] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 3 * BH, IW/2, BH);
gen_value[15]->minimum(0.);
gen_value[15]->maximum(10.);
gen_value[15]->step(0.01);
gen_value[15]->align(FL_ALIGN_RIGHT);
gen_value[15]->callback(general_options_ok_cb);
gen_value[16] = new Fl_Value_Input(L + 2 * WB + IW/2, 2 * WB + 3 * BH, IW/2, BH, "Polygon offset factor and units");
gen_value[16]->minimum(0.);
gen_value[16]->maximum(10.);
gen_value[16]->step(0.01);
gen_value[16]->align(FL_ALIGN_RIGHT);
gen_value[16]->callback(general_options_ok_cb);
gen_butt[4] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Always apply polygon offset");
gen_butt[4]->type(FL_TOGGLE_BUTTON);
gen_butt[4]->callback(general_options_ok_cb);
gen_value[11] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Number of quadric subdivisions");
gen_value[11]->minimum(3);
gen_value[11]->maximum(30);
gen_value[11]->step(1);
gen_value[11]->align(FL_ALIGN_RIGHT);
gen_value[11]->callback(general_options_ok_cb);
gen_value[6] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Point size");
gen_value[6]->minimum(0.1);
gen_value[6]->maximum(50);
gen_value[6]->step(0.1);
gen_value[6]->align(FL_ALIGN_RIGHT);
gen_value[6]->callback(general_options_ok_cb);
gen_value[7] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 7 * BH, IW, BH, "Line width");
gen_value[7]->minimum(0.1);
gen_value[7]->maximum(50);
gen_value[7]->step(0.1);
gen_value[7]->align(FL_ALIGN_RIGHT);
gen_value[7]->callback(general_options_ok_cb);
static Fl_Menu_Item menu_genvectype[] = {
{"Line", 0, 0, 0},
{"Arrow", 0, 0, 0},
{"Pyramid", 0, 0, 0},
{"3D arrow", 0, 0, 0},
{0}
};
gen_choice[0] = new Fl_Choice(L + 2 * WB, 2 * WB + 8 * BH, IW, BH, "Vector display");
gen_choice[0]->menu(menu_genvectype);
gen_choice[0]->align(FL_ALIGN_RIGHT);
gen_choice[0]->callback(general_options_ok_cb);
Fl_Button *b = new Fl_Button(L + 2 * IW - 2 * WB, 2 * WB + 8 * BH, (int)(1.5*BB), BH, "Edit arrow shape");
b->callback(general_arrow_param_cb);
gen_choice[1] = new Fl_Choice(L + 2 * WB, 2 * WB + 9 * BH, IW, BH, "Font");
gen_choice[1]->menu(menu_font_names);
gen_choice[1]->align(FL_ALIGN_RIGHT);
gen_choice[1]->callback(general_options_ok_cb);
gen_value[12] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 10 * BH, IW, BH, "Font size");
gen_value[12]->minimum(5);
gen_value[12]->maximum(40);
gen_value[12]->step(1);
gen_value[12]->align(FL_ALIGN_RIGHT);
gen_value[12]->callback(general_options_ok_cb);
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Light");
o->hide();
gen_value[2] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 1 * BH, IW/3, BH);
gen_value[2]->minimum(-1.);
gen_value[2]->maximum(1.);
gen_value[2]->step(0.01);
gen_value[2]->callback(general_options_ok_cb, (void*)"light_value");
gen_value[3] = new Fl_Value_Input(L + 2 * WB + IW / 3, 2 * WB + 1 * BH, IW/3, BH);
gen_value[3]->minimum(-1.);
gen_value[3]->maximum(1.);
gen_value[3]->step(0.01);
gen_value[3]->callback(general_options_ok_cb, (void*)"light_value");
gen_value[4] = new Fl_Value_Input(L + 2 * WB + 2 * IW / 3, 2 * WB + 1 * BH, IW/3, BH, "Light position");
gen_value[4]->minimum(-1.);
gen_value[4]->maximum(1.);
gen_value[4]->step(0.01);
gen_value[4]->align(FL_ALIGN_RIGHT);
gen_value[4]->callback(general_options_ok_cb, (void*)"light_value");
gen_value[13] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Light position divisor");
gen_value[13]->minimum(0.);
gen_value[13]->maximum(1.);
gen_value[13]->step(0.01);
gen_value[13]->align(FL_ALIGN_RIGHT);
gen_value[13]->callback(general_options_ok_cb);
gen_sphere = new SpherePosition_Widget(L + 2 * WB + 2 * IW, 2 * WB + 1 * BH, 2 * BH);
gen_sphere->callback(general_options_ok_cb, (void*)"light_sphere");
gen_value[1] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 3 * BH, IW, BH, "Material shininess");
gen_value[1]->minimum(0);
gen_value[1]->maximum(10);
gen_value[1]->step(0.1);
gen_value[1]->align(FL_ALIGN_RIGHT);
gen_value[1]->callback(general_options_ok_cb);
gen_value[0] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 4 * BH, IW, BH, "Material shininess exponent");
gen_value[0]->minimum(0);
gen_value[0]->maximum(128);
gen_value[0]->step(1);
gen_value[0]->align(FL_ALIGN_RIGHT);
gen_value[0]->callback(general_options_ok_cb);
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Color");
o->hide();
static Fl_Menu_Item menu_color_scheme[] = {
{"Dark", 0, 0, 0},
{"Light", 0, 0, 0},
{"Grayscale", 0, 0, 0},
{0}
};
gen_choice[3] = new Fl_Choice(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Predefined color scheme");
gen_choice[3]->menu(menu_color_scheme);
gen_choice[3]->align(FL_ALIGN_RIGHT);
gen_choice[3]->tooltip("(Alt+c)");
gen_choice[3]->callback(general_options_color_scheme_cb);
static Fl_Menu_Item menu_bg_grad[] = {
{"None", 0, 0, 0},
{"Vertical", 0, 0, 0},
{"Horizontal", 0, 0, 0},
{"Radial", 0, 0, 0},
{0}
};
gen_choice[5] = new Fl_Choice(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Background gradient");
gen_choice[5]->menu(menu_bg_grad);
gen_choice[5]->align(FL_ALIGN_RIGHT);
gen_choice[5]->callback(general_options_ok_cb);
Fl_Scroll *s = new Fl_Scroll(L + 2 * WB, 3 * WB + 3 * BH, IW + 20, height - 5 * WB - 3 * BH);
int i = 0;
while(GeneralOptions_Color[i].str) {
gen_col[i] = new Fl_Button(L + 2 * WB, 3 * WB + (3 + i) * BH, IW, BH, GeneralOptions_Color[i].str);
gen_col[i]->callback(color_cb, (void *)GeneralOptions_Color[i].function);
i++;
}
s->end();
o->end();
}
o->end();
}
gen_group->end();
// Geometry options
geo_group = new Fl_Group(L, 0, width, height, "Geometry Options");
geo_group->hide();
{
Fl_Tabs *o = new Fl_Tabs(L + WB, WB, width - 2 * WB, height - 2 * WB);
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "General");
o->hide();
geo_value[2] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Geometrical tolerance");
geo_value[2]->align(FL_ALIGN_RIGHT);
geo_value[2]->callback(geometry_options_ok_cb);
geo_butt[8] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 2 * BH, BW, BH, "Remove duplicate entities in GEO models");
geo_butt[8]->type(FL_TOGGLE_BUTTON);
geo_butt[8]->callback(geometry_options_ok_cb);
geo_butt[11] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW, BH, "Remove small edges in STEP, IGES and BRep models");
geo_butt[11]->type(FL_TOGGLE_BUTTON);
geo_butt[11]->callback(geometry_options_ok_cb);
geo_butt[12] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Remove small faces in STEP, IGES and BRep models");
geo_butt[12]->type(FL_TOGGLE_BUTTON);
geo_butt[12]->callback(geometry_options_ok_cb);
geo_butt[13] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 5 * BH, BW, BH, "Sew faces in STEP, IGES and BRep models");
geo_butt[13]->type(FL_TOGGLE_BUTTON);
geo_butt[13]->callback(geometry_options_ok_cb);
#if !defined(HAVE_OCC)
geo_butt[11]->deactivate();
geo_butt[12]->deactivate();
geo_butt[13]->deactivate();
#endif
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Visibility");
geo_butt[0] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 1 * BH, BW / 2 - WB, BH, "Points");
geo_butt[0]->tooltip("(Alt+p)");
geo_butt[0]->type(FL_TOGGLE_BUTTON);
geo_butt[0]->callback(geometry_options_ok_cb);
geo_butt[1] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 2 * BH, BW / 2 - WB, BH, "Lines");
geo_butt[1]->tooltip("(Alt+l)");
geo_butt[1]->type(FL_TOGGLE_BUTTON);
geo_butt[1]->callback(geometry_options_ok_cb);
geo_butt[2] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW / 2 - WB, BH, "Surfaces");
geo_butt[2]->tooltip("(Alt+s)");
geo_butt[2]->type(FL_TOGGLE_BUTTON);
geo_butt[2]->callback(geometry_options_ok_cb);
geo_butt[3] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW / 2 - WB, BH, "Volumes");
geo_butt[3]->tooltip("(Alt+v)");
geo_butt[3]->type(FL_TOGGLE_BUTTON);
geo_butt[3]->callback(geometry_options_ok_cb);
geo_butt[4] = new Fl_Check_Button(L + width / 2, 2 * WB + 1 * BH, BW / 2 - WB, BH, "Point numbers");
geo_butt[4]->type(FL_TOGGLE_BUTTON);
geo_butt[4]->callback(geometry_options_ok_cb);
geo_butt[5] = new Fl_Check_Button(L + width / 2, 2 * WB + 2 * BH, BW / 2 - WB, BH, "Line numbers");
geo_butt[5]->type(FL_TOGGLE_BUTTON);
geo_butt[5]->callback(geometry_options_ok_cb);
geo_butt[6] = new Fl_Check_Button(L + width / 2, 2 * WB + 3 * BH, BW / 2 - WB, BH, "Surface numbers");
geo_butt[6]->type(FL_TOGGLE_BUTTON);
geo_butt[6]->callback(geometry_options_ok_cb);
geo_butt[7] = new Fl_Check_Button(L + width / 2, 2 * WB + 4 * BH, BW / 2 - WB, BH, "Volume numbers");
geo_butt[7]->type(FL_TOGGLE_BUTTON);
geo_butt[7]->callback(geometry_options_ok_cb);
geo_value[0] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Normals");
geo_value[0]->minimum(0);
geo_value[0]->maximum(500);
geo_value[0]->step(1);
geo_value[0]->align(FL_ALIGN_RIGHT);
geo_value[0]->when(FL_WHEN_RELEASE);
geo_value[0]->callback(geometry_options_ok_cb);
geo_value[1] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Tangents");
geo_value[1]->minimum(0);
geo_value[1]->maximum(500);
geo_value[1]->step(1);
geo_value[1]->align(FL_ALIGN_RIGHT);
geo_value[1]->when(FL_WHEN_RELEASE);
geo_value[1]->callback(geometry_options_ok_cb);
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Aspect");
o->hide();
geo_choice[0] = new Fl_Choice(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Point display");
geo_choice[0]->menu(menu_point_display);
geo_choice[0]->align(FL_ALIGN_RIGHT);
geo_choice[0]->callback(geometry_options_ok_cb);
geo_value[3] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Point size");
geo_value[3]->minimum(0.1);
geo_value[3]->maximum(50);
geo_value[3]->step(0.1);
geo_value[3]->align(FL_ALIGN_RIGHT);
geo_value[3]->callback(geometry_options_ok_cb);
geo_value[5] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 3 * BH, IW, BH, "Selected point size");
geo_value[5]->minimum(0.1);
geo_value[5]->maximum(50);
geo_value[5]->step(0.1);
geo_value[5]->align(FL_ALIGN_RIGHT);
geo_value[5]->callback(geometry_options_ok_cb);
geo_choice[1] = new Fl_Choice(L + 2 * WB, 2 * WB + 4 * BH, IW, BH, "Line display");
geo_choice[1]->menu(menu_line_display);
geo_choice[1]->align(FL_ALIGN_RIGHT);
geo_choice[1]->callback(geometry_options_ok_cb);
geo_value[4] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Line width");
geo_value[4]->minimum(0.1);
geo_value[4]->maximum(50);
geo_value[4]->step(0.1);
geo_value[4]->align(FL_ALIGN_RIGHT);
geo_value[4]->callback(geometry_options_ok_cb);
geo_value[6] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Selected line width");
geo_value[6]->minimum(0.1);
geo_value[6]->maximum(50);
geo_value[6]->step(0.1);
geo_value[6]->align(FL_ALIGN_RIGHT);
geo_value[6]->callback(geometry_options_ok_cb);
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Light");
o->hide();
geo_butt[9] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 1 * BH, BW, BH, "Enable lighting");
geo_butt[9]->type(FL_TOGGLE_BUTTON);
geo_butt[9]->tooltip("(Alt+w)");
geo_butt[9]->callback(geometry_options_ok_cb);
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Color");
o->hide();
geo_butt[10] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 1 * BH, BW, BH, "Highlight orphan entities");
geo_butt[10]->type(FL_TOGGLE_BUTTON);
geo_butt[10]->callback(geometry_options_ok_cb);
Fl_Scroll *s = new Fl_Scroll(L + 2 * WB, 2 * WB + 2 * BH, IW + 20, height - 4 * WB - 2 * BH);
int i = 0;
while(GeometryOptions_Color[i].str) {
geo_col[i] = new Fl_Button(L + 2 * WB, 2 * WB + (2 + i) * BH, IW, BH, GeometryOptions_Color[i].str);
geo_col[i]->callback(color_cb, (void *)GeometryOptions_Color[i].function);
i++;
}
s->end();
o->end();
}
o->end();
}
geo_group->end();
// Mesh options
mesh_group = new Fl_Group(L, 0, width, height, "Mesh Options");
mesh_group->hide();
{
Fl_Tabs *o = new Fl_Tabs(L + WB, WB, width - 2 * WB, height - 2 * WB);
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "General");
o->hide();
static Fl_Menu_Item menu_2d_algo[] = {
{"MeshAdapt", 0, 0, 0},
{"Delaunay", 0, 0, 0},
{0}
};
static Fl_Menu_Item menu_3d_algo[] = {
{"Delaunay", 0, 0, 0},
{"Netgen", 0, 0, 0},
{0}
};
static Fl_Menu_Item menu_recombine_algo[] = {
{"Mixed Tri-Quads", 0, 0, 0},
{"All Quads", 0, 0, 0},
{0}
};
mesh_choice[2] = new Fl_Choice(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "2D algorithm");
mesh_choice[2]->menu(menu_2d_algo);
mesh_choice[2]->align(FL_ALIGN_RIGHT);
mesh_choice[2]->callback(mesh_options_ok_cb);
// not reimplemented yet
((Fl_Menu_Item*)mesh_choice[2]->menu())[1].deactivate();
mesh_choice[3] = new Fl_Choice(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "3D algorithm");
mesh_choice[3]->menu(menu_3d_algo);
mesh_choice[3]->align(FL_ALIGN_RIGHT);
mesh_choice[3]->callback(mesh_options_ok_cb);
mesh_choice[5] = new Fl_Choice(L + 2 * WB, 2 * WB + 3 * BH, IW, BH, "Recombine algorithm");
mesh_choice[5]->menu(menu_recombine_algo);
mesh_choice[5]->align(FL_ALIGN_RIGHT);
mesh_choice[5]->callback(mesh_options_ok_cb);
// not reimplemented yet
((Fl_Menu_Item*)mesh_choice[5]->menu())[1].deactivate();
mesh_value[0] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 4 * BH, IW, BH, "Number of smoothing steps");
mesh_value[0]->minimum(0);
mesh_value[0]->maximum(100);
mesh_value[0]->step(1);
mesh_value[0]->align(FL_ALIGN_RIGHT);
mesh_value[0]->callback(mesh_options_ok_cb);
mesh_value[2] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Characteristic length factor");
mesh_value[2]->minimum(0.001);
mesh_value[2]->maximum(1000);
mesh_value[2]->step(0.01);
mesh_value[2]->align(FL_ALIGN_RIGHT);
mesh_value[2]->callback(mesh_options_ok_cb);
mesh_value[3] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Element order");
mesh_value[3]->minimum(1);
// FIXME: this makes it possible to set > 2 by hand, but not by
// dragging (>2 is too buggy for general use)
mesh_value[3]->maximum(2);
mesh_value[3]->step(1);
mesh_value[3]->align(FL_ALIGN_RIGHT);
mesh_value[3]->callback(mesh_options_ok_cb);
mesh_butt[4] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 7 * BH, BW, BH, "Use incomplete high order elements (8-node quads, etc.)");
mesh_butt[4]->type(FL_TOGGLE_BUTTON);
mesh_butt[4]->callback(mesh_options_ok_cb);
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Advanced");
o->hide();
mesh_butt[1] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 1 * BH, BW, BH, "Compute characteritic lengths from curvatures" );
mesh_butt[1]->type(FL_TOGGLE_BUTTON);
mesh_butt[1]->callback(mesh_options_ok_cb);
mesh_butt[5] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 2 * BH, BW, BH, "Constrain background mesh with other length fields");
mesh_butt[5]->type(FL_TOGGLE_BUTTON);
mesh_butt[5]->callback(mesh_options_ok_cb);
mesh_butt[2] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW, BH, "Optimize quality of tetrahedra");
mesh_butt[2]->type(FL_TOGGLE_BUTTON);
#if !defined(HAVE_NETGEN)
mesh_butt[2]->deactivate();
#endif
mesh_butt[2]->callback(mesh_options_ok_cb);
mesh_butt[3] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Optimize high order mesh (only for 2D-plane)");
mesh_butt[3]->type(FL_TOGGLE_BUTTON);
mesh_butt[3]->callback(mesh_options_ok_cb);
mesh_butt[21] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 5 * BH, BW, BH, "Impose C1 continuity (only for 2D-plane, order 2 and 3)");
mesh_butt[21]->type(FL_TOGGLE_BUTTON);
mesh_butt[21]->callback(mesh_options_ok_cb);
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Visibility");
mesh_butt[6] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 1 * BH, BW / 2 - WB, BH, "Nodes");
mesh_butt[6]->tooltip("(Alt+Shift+p)");
mesh_butt[6]->type(FL_TOGGLE_BUTTON);
mesh_butt[6]->callback(mesh_options_ok_cb);
mesh_butt[7] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 2 * BH, BW / 2 - WB, BH, "Lines");
mesh_butt[7]->tooltip("(Alt+Shift+l)");
mesh_butt[7]->type(FL_TOGGLE_BUTTON);
mesh_butt[7]->callback(mesh_options_ok_cb);
mesh_butt[8] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW / 2 - WB, BH, "Surface edges");
mesh_butt[8]->tooltip("(Alt+Shift+s)");
mesh_butt[8]->type(FL_TOGGLE_BUTTON);
mesh_butt[8]->callback(mesh_options_ok_cb);
mesh_butt[9] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW / 2 - WB, BH, "Surface faces");
mesh_butt[9]->tooltip("(Alt+Shift+d)");
mesh_butt[9]->type(FL_TOGGLE_BUTTON);
mesh_butt[9]->callback(mesh_options_ok_cb);
mesh_butt[10] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 5 * BH, BW / 2 - WB, BH, "Volume edges");
mesh_butt[10]->tooltip("(Alt+Shift+v)");
mesh_butt[10]->type(FL_TOGGLE_BUTTON);
mesh_butt[10]->callback(mesh_options_ok_cb);
mesh_butt[11] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 6 * BH, BW / 2 - WB, BH, "Volume faces");
mesh_butt[11]->tooltip("(Alt+Shift+b)");
mesh_butt[11]->type(FL_TOGGLE_BUTTON);
mesh_butt[11]->callback(mesh_options_ok_cb);
mesh_butt[12] = new Fl_Check_Button(L + width / 2, 2 * WB + 1 * BH, BW / 2 - WB, BH, "Node labels");
mesh_butt[12]->type(FL_TOGGLE_BUTTON);
mesh_butt[12]->callback(mesh_options_ok_cb);
mesh_butt[13] = new Fl_Check_Button(L + width / 2, 2 * WB + 2 * BH, BW / 2 - WB, BH, "Line labels");
mesh_butt[13]->type(FL_TOGGLE_BUTTON);
mesh_butt[13]->callback(mesh_options_ok_cb);
mesh_butt[14] = new Fl_Check_Button(L + width / 2, 2 * WB + 3 * BH, BW / 2 - WB, BH, "Surface labels");
mesh_butt[14]->type(FL_TOGGLE_BUTTON);
mesh_butt[14]->callback(mesh_options_ok_cb);
mesh_butt[15] = new Fl_Check_Button(L + width / 2, 2 * WB + 4 * BH, BW / 2 - WB, BH, "Volume labels");
mesh_butt[15]->type(FL_TOGGLE_BUTTON);
mesh_butt[15]->callback(mesh_options_ok_cb);
static Fl_Menu_Item menu_label_type[] = {
{"Number", 0, 0, 0},
{"Elementary entity", 0, 0, 0},
{"Physical group", 0, 0, 0},
{"Mesh partition", 0, 0, 0},
{"Coordinates", 0, 0, 0},
{0}
};
mesh_choice[7] = new Fl_Choice(L + width / 2, 2 * WB + 5 * BH, width/4 - 2*WB, BH, "Label type");
mesh_choice[7]->menu(menu_label_type);
mesh_choice[7]->align(FL_ALIGN_RIGHT);
mesh_choice[7]->callback(mesh_options_ok_cb);
mesh_value[12] = new Fl_Value_Input(L + width / 2, 2 * WB + 6 * BH, width/4 - 2*WB, BH, "Label frequency");
mesh_value[12]->minimum(0);
mesh_value[12]->maximum(100);
mesh_value[12]->step(1);
mesh_value[12]->align(FL_ALIGN_RIGHT);
mesh_value[12]->when(FL_WHEN_RELEASE);
mesh_value[12]->callback(mesh_options_ok_cb);
static Fl_Menu_Item menu_mesh_element_types[] = {
{"Triangles", 0, 0, 0, FL_MENU_TOGGLE},
{"Quadrangles", 0, 0, 0, FL_MENU_TOGGLE},
{"Tetrahedra", 0, 0, 0, FL_MENU_TOGGLE},
{"Hexahedra", 0, 0, 0, FL_MENU_TOGGLE},
{"Prisms", 0, 0, 0, FL_MENU_TOGGLE},
{"Pyramids", 0, 0, 0, FL_MENU_TOGGLE},
{0}
};
mesh_menu_butt = new Fl_Menu_Button(L + 2 * WB, 2 * WB + 7 * BH, IW, BH, "Elements");
mesh_menu_butt->menu(menu_mesh_element_types);
mesh_menu_butt->callback(mesh_options_ok_cb);
mesh_value[4] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 8 * BH, IW / 4, BH);
mesh_value[4]->minimum(0);
mesh_value[4]->maximum(1);
mesh_value[4]->step(0.01);
mesh_value[4]->align(FL_ALIGN_RIGHT);
mesh_value[4]->when(FL_WHEN_RELEASE);
mesh_value[4]->callback(mesh_options_ok_cb);
mesh_value[5] = new Fl_Value_Input(L + 2 * WB + IW / 4, 2 * WB + 8 * BH, IW / 2 - IW / 4, BH);
mesh_value[5]->minimum(0);
mesh_value[5]->maximum(1);
mesh_value[5]->step(0.01);
mesh_value[5]->align(FL_ALIGN_RIGHT);
mesh_value[5]->when(FL_WHEN_RELEASE);
mesh_value[5]->callback(mesh_options_ok_cb);
static Fl_Menu_Item menu_quality_type[] = {
{"Gamma", 0, 0, 0},
{"Eta", 0, 0, 0},
{"Rho", 0, 0, 0},
{0}
};
mesh_choice[6] = new Fl_Choice(L + 2 * WB + IW / 2, 2 * WB + 8 * BH, IW/2, BH, "Quality range");
mesh_choice[6]->menu(menu_quality_type);
mesh_choice[6]->align(FL_ALIGN_RIGHT);
mesh_choice[6]->callback(mesh_options_ok_cb);
mesh_value[6] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 9 * BH, IW / 2, BH);
mesh_value[6]->align(FL_ALIGN_RIGHT);
mesh_value[6]->when(FL_WHEN_RELEASE);
mesh_value[6]->callback(mesh_options_ok_cb);
mesh_value[7] = new Fl_Value_Input(L + 2 * WB + IW / 2, 2 * WB + 9 * BH, IW / 2, BH, "Size range");
mesh_value[7]->align(FL_ALIGN_RIGHT);
mesh_value[7]->when(FL_WHEN_RELEASE);
mesh_value[7]->callback(mesh_options_ok_cb);
mesh_value[8] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 10 * BH, IW, BH, "Normals");
mesh_value[8]->minimum(0);
mesh_value[8]->maximum(500);
mesh_value[8]->step(1);
mesh_value[8]->align(FL_ALIGN_RIGHT);
mesh_value[8]->when(FL_WHEN_RELEASE);
mesh_value[8]->callback(mesh_options_ok_cb);
mesh_value[13] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 11 * BH, IW, BH, "Tangents");
mesh_value[13]->minimum(0);
mesh_value[13]->maximum(200);
mesh_value[13]->step(1.0);
mesh_value[13]->align(FL_ALIGN_RIGHT);
mesh_value[13]->when(FL_WHEN_RELEASE);
mesh_value[13]->callback(mesh_options_ok_cb);
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Cutting");
o->hide();
mesh_butt[16] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 1 * BH, BW, BH, "Enable element-by-element cutting plane");
mesh_butt[16]->type(FL_TOGGLE_BUTTON);
mesh_butt[16]->callback(mesh_options_ok_cb, (void*)"mesh_cut_plane");
mesh_cut_plane = new Fl_Group(L + 2 * WB, 2 * WB + 2 * BH, width - 2 * WB, 4 * BH, 0);
int ii = fontsize;
Fl_Button *invert = new Fl_Button(L + 2 * WB, 2 * WB + 2 * BH, ii, 4*BH, "-");
invert->tooltip("Invert orientation");
invert->callback(mesh_options_ok_cb, (void*)"cut_plane_invert");
mesh_value[14] = new Fl_Value_Input(L + 2 * WB + ii, 2 * WB + 2 * BH, IW - ii, BH, "A");
mesh_value[14]->align(FL_ALIGN_RIGHT);
mesh_value[14]->step(0.01);
mesh_value[14]->minimum(-1.0);
mesh_value[14]->maximum(1.0);
mesh_value[14]->callback(mesh_options_ok_cb);
mesh_value[15] = new Fl_Value_Input(L + 2 * WB + ii, 2 * WB + 3 * BH, IW - ii, BH, "B");
mesh_value[15]->align(FL_ALIGN_RIGHT);
mesh_value[15]->step(0.01);
mesh_value[15]->minimum(-1.0);
mesh_value[15]->maximum(1.0);
mesh_value[15]->callback(mesh_options_ok_cb);
mesh_value[16] = new Fl_Value_Input(L + 2 * WB + ii, 2 * WB + 4 * BH, IW - ii, BH, "C");
mesh_value[16]->align(FL_ALIGN_RIGHT);
mesh_value[16]->step(0.01);
mesh_value[16]->minimum(-1.0);
mesh_value[16]->maximum(1.0);
mesh_value[16]->callback(mesh_options_ok_cb);
mesh_value[17] = new Fl_Value_Input(L + 2 * WB + ii, 2 * WB + 5 * BH, IW - ii, BH, "D");
mesh_value[17]->align(FL_ALIGN_RIGHT);
mesh_value[17]->step(0.01);
mesh_value[17]->minimum(-1.0);
mesh_value[17]->maximum(1.0);
mesh_value[17]->callback(mesh_options_ok_cb);
mesh_cut_plane->end();
mesh_butt[22] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 6 * BH, BW, BH, "Draw only intersecting volume layer");
mesh_butt[22]->type(FL_TOGGLE_BUTTON);
mesh_butt[22]->callback(mesh_options_ok_cb);
mesh_butt[23] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 7 * BH, BW, BH, "Cut only volume elements");
mesh_butt[23]->type(FL_TOGGLE_BUTTON);
mesh_butt[23]->callback(mesh_options_ok_cb);
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Aspect");
o->hide();
mesh_value[9] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Element shrinking factor");
mesh_value[9]->minimum(0);
mesh_value[9]->maximum(1);
mesh_value[9]->step(0.01);
mesh_value[9]->align(FL_ALIGN_RIGHT);
mesh_value[9]->when(FL_WHEN_RELEASE);
mesh_value[9]->callback(mesh_options_ok_cb);
mesh_choice[0] = new Fl_Choice(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Point display");
mesh_choice[0]->menu(menu_point_display);
mesh_choice[0]->align(FL_ALIGN_RIGHT);
mesh_choice[0]->callback(mesh_options_ok_cb);
mesh_value[10] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 3 * BH, IW, BH, "Point size");
mesh_value[10]->minimum(0.1);
mesh_value[10]->maximum(50);
mesh_value[10]->step(0.1);
mesh_value[10]->align(FL_ALIGN_RIGHT);
mesh_value[10]->callback(mesh_options_ok_cb);
mesh_value[11] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 4 * BH, IW, BH, "Line width");
mesh_value[11]->minimum(0.1);
mesh_value[11]->maximum(50);
mesh_value[11]->step(0.1);
mesh_value[11]->align(FL_ALIGN_RIGHT);
mesh_value[11]->callback(mesh_options_ok_cb);
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Light");
o->hide();
mesh_butt[17] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 1 * BH, BW, BH, "Enable lighting");
mesh_butt[17]->tooltip("(Alt+w)");
mesh_butt[17]->type(FL_TOGGLE_BUTTON);
mesh_butt[17]->callback(mesh_options_ok_cb, (void*)"mesh_light");
mesh_butt[20] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 2 * BH, BW, BH, "Enable lighting of lines");
mesh_butt[20]->type(FL_TOGGLE_BUTTON);
mesh_butt[20]->callback(mesh_options_ok_cb);
mesh_butt[18] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW, BH, "Use two-side lighting");
mesh_butt[18]->type(FL_TOGGLE_BUTTON);
mesh_butt[18]->callback(mesh_options_ok_cb);
mesh_butt[0] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Reverse all normals");
mesh_butt[0]->tooltip("(Alt+Shift+w)");
mesh_butt[0]->type(FL_TOGGLE_BUTTON);
mesh_butt[0]->callback(mesh_options_ok_cb);
mesh_butt[19] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 5 * BH, BW, BH, "Smooth normals");
mesh_butt[19]->type(FL_TOGGLE_BUTTON);
mesh_butt[19]->callback(mesh_options_ok_cb);
mesh_value[18] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Smoothing threshold angle");
mesh_value[18]->minimum(0.);
mesh_value[18]->maximum(180.);
mesh_value[18]->step(1.);
mesh_value[18]->align(FL_ALIGN_RIGHT);
mesh_value[18]->when(FL_WHEN_RELEASE);
mesh_value[18]->callback(mesh_options_ok_cb);
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Color");
o->hide();
static Fl_Menu_Item menu_mesh_color[] = {
{"By element type", 0, 0, 0},
{"By elementary entity", 0, 0, 0},
{"By physical group", 0, 0, 0},
{"By mesh partition", 0, 0, 0},
{0}
};
mesh_choice[4] = new Fl_Choice(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Coloring mode");
mesh_choice[4]->menu(menu_mesh_color);
mesh_choice[4]->align(FL_ALIGN_RIGHT);
mesh_choice[4]->callback(mesh_options_ok_cb);
Fl_Scroll *s = new Fl_Scroll(L + 2 * WB, 3 * WB + 2 * BH, IW + 20, height - 5 * WB - 2 * BH);
int i = 0;
while(MeshOptions_Color[i].str) {
mesh_col[i] = new Fl_Button(L + 2 * WB, 3 * WB + (2 + i) * BH, IW, BH, MeshOptions_Color[i].str);
mesh_col[i]->callback(color_cb, (void *)MeshOptions_Color[i].function);
i++;
}
s->end();
o->end();
}
o->end();
}
mesh_group->end();
// Solver options
solver_group = new Fl_Group(L, 0, width, height, "Solver Options");
solver_group->hide();
{
Fl_Tabs *o = new Fl_Tabs(L + WB, WB, width - 2 * WB, height - 2 * WB);
{
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "General");
solver_value[0] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Maximum delay for solver response");
solver_value[0]->minimum(0);
solver_value[0]->maximum(10);
solver_value[0]->step(1);
solver_value[0]->align(FL_ALIGN_RIGHT);
solver_value[0]->callback(solver_options_ok_cb);
solver_input[0] = new Fl_Input(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Socket name");
solver_input[0]->align(FL_ALIGN_RIGHT);
solver_input[0]->callback(solver_options_ok_cb);
solver_butt[0] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW, BH, "Always listen to incoming connection requests");
solver_butt[0]->type(FL_TOGGLE_BUTTON);
solver_butt[0]->callback(solver_options_ok_cb);
o->end();
}
}
o->end();
}
solver_group->end();
// Post-processing options
post_group = new Fl_Group(L, 0, width, height, "Post-processing Options");
post_group->hide();
{
Fl_Tabs *o = new Fl_Tabs(L + WB, WB, width - 2 * WB, height - 2 * WB);
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "General");
static Fl_Menu_Item menu_links[] = {
{"None", 0, 0, 0},
{"Apply next changes to all visible views", 0, 0, 0},
{"Apply next changes to all views", 0, 0, 0},
{"Force same options for all visible views", 0, 0, 0},
{"Force same options for all views", 0, 0, 0},
{0}
};
post_choice[0] = new Fl_Choice(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "View links");
post_choice[0]->menu(menu_links);
post_choice[0]->align(FL_ALIGN_RIGHT);
post_choice[0]->callback(post_options_ok_cb);
post_value[0] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Animation delay");
post_value[0]->minimum(0);
post_value[0]->maximum(10);
post_value[0]->step(0.01);
post_value[0]->align(FL_ALIGN_RIGHT);
post_value[0]->callback(post_options_ok_cb);
post_butt[0] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW, BH, "Cycle through views instead of time steps");
post_butt[0]->type(FL_TOGGLE_BUTTON);
post_butt[0]->callback(post_options_ok_cb);
post_butt[1] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Remove original views after combination");
post_butt[1]->type(FL_TOGGLE_BUTTON);
post_butt[1]->callback(post_options_ok_cb);
post_butt[2] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 5 * BH, BW, BH, "Draw value scales horizontally");
post_butt[2]->type(FL_TOGGLE_BUTTON);
post_butt[2]->callback(post_options_ok_cb);
o->end();
}
o->end();
}
post_group->end();
// View options
view_number = -1;
view_group = new Fl_Group(L, 0, width, height, "View Options");
view_group->hide();
{
Fl_Tabs *o = new Fl_Tabs(L + WB, WB, width - 2 * WB, height - 2 * WB);
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "General");
static Fl_Menu_Item menu_plot_type[] = {
{"3D", 0, 0, 0},
{"2D space", 0, 0, 0},
{"2D time", 0, 0, 0},
{0}
};
view_choice[13] = new Fl_Choice(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Plot type");
view_choice[13]->menu(menu_plot_type);
view_choice[13]->align(FL_ALIGN_RIGHT);
view_choice[13]->callback(view_options_ok_cb);
view_input[0] = new Fl_Input(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "View name");
view_input[0]->align(FL_ALIGN_RIGHT);
view_input[0]->callback(view_options_ok_cb);
int sw = (int)(1.5 * fontsize);
view_butt_rep[0] = new Fl_Repeat_Button(L + 2 * WB, 2 * WB + 3 * BH, sw, BH, "-");
view_butt_rep[0]->callback(view_options_timestep_decr_cb);
view_butt_rep[1] = new Fl_Repeat_Button(L + 2 * WB + IW - sw, 2 * WB + 3 * BH, sw, BH, "+");
view_butt_rep[1]->callback(view_options_timestep_incr_cb);
view_value[50] = new Fl_Value_Input(L + 2 * WB + sw, 2 * WB + 3 * BH, IW - 2 * sw, BH);
view_value[50]->callback(view_options_timestep_cb);
view_value[50]->align(FL_ALIGN_RIGHT);
view_value[50]->minimum(0);
view_value[50]->maximum(0);
view_value[50]->step(1);
Fl_Box *a = new Fl_Box(L + 2 * WB + IW, 2 * WB + 3 * BH, IW / 2, BH, "Time step");
a->box(FL_NO_BOX);
a->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
view_range = new Fl_Group(L + 2 * WB, 2 * WB + 4 * BH, width - 4 * WB, 8 * BH);
view_value[30] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 4 * BH, IW, BH, "Number of intervals");
view_value[30]->align(FL_ALIGN_RIGHT);
view_value[30]->minimum(1);
view_value[30]->maximum(256);
view_value[30]->step(1);
view_value[30]->when(FL_WHEN_RELEASE);
view_value[30]->callback(view_options_ok_cb);
static Fl_Menu_Item menu_iso[] = {
{"Iso-values", 0, 0, 0},
{"Filled iso-values", 0, 0, 0},
{"Continuous map", 0, 0, 0},
{"Numeric values", 0, 0, 0},
{0}
};
view_choice[0] = new Fl_Choice(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Intervals type");
view_choice[0]->menu(menu_iso);
view_choice[0]->align(FL_ALIGN_RIGHT);
view_choice[0]->tooltip("(Alt+t)");
view_choice[0]->callback(view_options_ok_cb);
static Fl_Menu_Item menu_range[] = {
{"Default", 0, 0, 0},
{"Per time step", 0, 0, 0},
{"Custom", 0, 0, 0},
{0}
};
view_choice[7] = new Fl_Choice(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Range mode");
view_choice[7]->menu(menu_range);
view_choice[7]->align(FL_ALIGN_RIGHT);
view_choice[7]->tooltip("(Alt+r)");
view_choice[7]->callback(view_options_ok_cb, (void*)"custom_range");
int sw2 = (int)(2.5 * fontsize);
view_push_butt[1] = new Fl_Button(L + 2 * WB, 2 * WB + 7 * BH, sw2, BH, "Min");
view_push_butt[1]->callback(view_options_ok_cb, (void*)"range_min");
view_value[31] = new Fl_Value_Input(L + 2 * WB + sw2, 2 * WB + 7 * BH, IW - sw2, BH, "Custom minimum");
view_value[31]->align(FL_ALIGN_RIGHT);
view_value[31]->when(FL_WHEN_RELEASE);
view_value[31]->callback(view_options_ok_cb);
view_push_butt[2] = new Fl_Button(L + 2 * WB, 2 * WB + 8 * BH, sw2, BH, "Max");
view_push_butt[2]->callback(view_options_ok_cb, (void*)"range_max");
view_value[32] = new Fl_Value_Input(L + 2 * WB + sw2, 2 * WB + 8 * BH, IW - sw2, BH, "Custom maximum");
view_value[32]->align(FL_ALIGN_RIGHT);
view_value[32]->when(FL_WHEN_RELEASE);
view_value[32]->callback(view_options_ok_cb);
view_butt[38] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 9 * BH, BW, BH, "Saturate out-of-range values");
view_butt[38]->type(FL_TOGGLE_BUTTON);
view_butt[38]->callback(view_options_ok_cb);
static Fl_Menu_Item menu_scale[] = {
{"Linear", 0, 0, 0},
{"Logarithmic", 0, 0, 0},
{"Double logarithmic", 0, 0, 0},
{0}
};
view_choice[1] = new Fl_Choice(L + 2 * WB, 2 * WB + 10 * BH, IW, BH, "Value scale mode");
view_choice[1]->menu(menu_scale);
view_choice[1]->align(FL_ALIGN_RIGHT);
view_choice[1]->callback(view_options_ok_cb);
view_input[1] = new Fl_Input(L + 2 * WB, 2 * WB + 11 * BH, IW, BH, "Number display format");
view_input[1]->align(FL_ALIGN_RIGHT);
view_input[1]->callback(view_options_ok_cb);
view_range->end();
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Axes");
o->hide();
view_choice[8] = new Fl_Choice(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Axes mode");
view_choice[8]->menu(menu_axes_mode);
view_choice[8]->align(FL_ALIGN_RIGHT);
view_choice[8]->tooltip("(Alt+a)");
view_choice[8]->callback(view_options_ok_cb, (void*)"view_axes");
view_value[3] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 2 * BH, IW/3, BH);
view_value[3]->minimum(0.);
view_value[3]->step(1);
view_value[3]->maximum(100);
view_value[3]->callback(view_options_ok_cb);
view_value[4] = new Fl_Value_Input(L + 2 * WB + 1*IW/3, 2 * WB + 2 * BH, IW/3, BH);
view_value[4]->minimum(0.);
view_value[4]->step(1);
view_value[4]->maximum(100);
view_value[4]->callback(view_options_ok_cb);
view_value[5] = new Fl_Value_Input(L + 2 * WB + 2*IW/3, 2 * WB + 2 * BH, IW/3, BH, "Axes tics");
view_value[5]->minimum(0.);
view_value[5]->step(1);
view_value[5]->maximum(100);
view_value[5]->align(FL_ALIGN_RIGHT);
view_value[5]->callback(view_options_ok_cb);
view_input[7] = new Fl_Input(L + 2 * WB, 2 * WB + 3 * BH, IW/3, BH);
view_input[7]->callback(view_options_ok_cb);
view_input[8] = new Fl_Input(L + 2 * WB + 1*IW/3, 2 * WB + 3 * BH, IW/3, BH);
view_input[8]->callback(view_options_ok_cb);
view_input[9] = new Fl_Input(L + 2 * WB + 2*IW/3, 2 * WB + 3 * BH, IW/3, BH, "Axes format");
view_input[9]->align(FL_ALIGN_RIGHT);
view_input[9]->callback(view_options_ok_cb);
view_input[10] = new Fl_Input(L + 2 * WB, 2 * WB + 4 * BH, IW/3, BH);
view_input[10]->callback(view_options_ok_cb);
view_input[11] = new Fl_Input(L + 2 * WB + 1*IW/3, 2 * WB + 4 * BH, IW/3, BH);
view_input[11]->callback(view_options_ok_cb);
view_input[12] = new Fl_Input(L + 2 * WB + 2*IW/3, 2 * WB + 4 * BH, IW/3, BH, "Axes labels");
view_input[12]->align(FL_ALIGN_RIGHT);
view_input[12]->callback(view_options_ok_cb);
view_butt[25] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 5 * BH, BW, BH, "Set position and size of 3D axes automatically");
view_butt[25]->type(FL_TOGGLE_BUTTON);
view_butt[25]->callback(view_options_ok_cb, (void*)"view_axes_auto_3d");
view_value[13] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 6 * BH, IW / 3, BH);
view_value[13]->callback(view_options_ok_cb);
view_value[14] = new Fl_Value_Input(L + 2 * WB + IW / 3, 2 * WB + 6 * BH, IW / 3, BH);
view_value[14]->callback(view_options_ok_cb);
view_value[15] = new Fl_Value_Input(L + 2 * WB + 2 * IW / 3, 2 * WB + 6 * BH, IW / 3, BH, "3D axes minimum");
view_value[15]->align(FL_ALIGN_RIGHT);
view_value[15]->callback(view_options_ok_cb);
view_value[16] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 7 * BH, IW / 3, BH);
view_value[16]->callback(view_options_ok_cb);
view_value[17] = new Fl_Value_Input(L + 2 * WB + IW / 3, 2 * WB + 7 * BH, IW / 3, BH);
view_value[17]->callback(view_options_ok_cb);
view_value[18] = new Fl_Value_Input(L + 2 * WB + 2 * IW / 3, 2 * WB + 7 * BH, IW / 3, BH, "3D axes maximum");
view_value[18]->align(FL_ALIGN_RIGHT);
view_value[18]->callback(view_options_ok_cb);
view_butt[7] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 8 * BH, BW, BH, "Set position and size of 2D axes or value scale automatically");
view_butt[7]->type(FL_TOGGLE_BUTTON);
view_butt[7]->callback(view_options_ok_cb, (void*)"view_axes_auto_2d");
view_value[20] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 9 * BH, IW / 2, BH);
view_value[20]->minimum(-2000);
view_value[20]->maximum(2000);
view_value[20]->step(1);
view_value[20]->callback(view_options_ok_cb);
view_value[21] = new Fl_Value_Input(L + 2 * WB + IW / 2, 2 * WB + 9 * BH, IW / 2, BH, "2D axes or value scale position");
view_value[21]->align(FL_ALIGN_RIGHT);
view_value[21]->minimum(-2000);
view_value[21]->maximum(2000);
view_value[21]->step(1);
view_value[21]->callback(view_options_ok_cb);
view_value[22] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 10 * BH, IW / 2, BH);
view_value[22]->minimum(0);
view_value[22]->maximum(2000);
view_value[22]->step(1);
view_value[22]->callback(view_options_ok_cb);
view_value[23] = new Fl_Value_Input(L + 2 * WB + IW / 2, 2 * WB + 10 * BH, IW / 2, BH, "2D axes or value scale size");
view_value[23]->align(FL_ALIGN_RIGHT);
view_value[23]->minimum(0);
view_value[23]->maximum(2000);
view_value[23]->step(1);
view_value[23]->callback(view_options_ok_cb);
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Visibility");
o->hide();
view_butt[4] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 1 * BH, BW, BH, "Show value scale");
view_butt[4]->tooltip("(Alt+i)");
view_butt[4]->type(FL_TOGGLE_BUTTON);
view_butt[4]->callback(view_options_ok_cb);
static Fl_Menu_Item time_display[] = {
{"None", 0, 0, 0},
{"Value if multi-step", 0, 0, 0},
{"Value", 0, 0, 0},
{"Step if multi-step", 0, 0, 0},
{"Step", 0, 0, 0},
{0}
};
view_choice[12] = new Fl_Choice(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Time display mode");
view_choice[12]->menu(time_display);
view_choice[12]->align(FL_ALIGN_RIGHT);
view_choice[12]->callback(view_options_ok_cb);
view_butt[5] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW, BH, "Show annotations");
view_butt[5]->tooltip("(Alt+n)");
view_butt[5]->type(FL_TOGGLE_BUTTON);
view_butt[5]->callback(view_options_ok_cb);
view_butt[10] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Draw element outlines");
view_butt[10]->type(FL_TOGGLE_BUTTON);
view_butt[10]->callback(view_options_ok_cb);
static Fl_Menu_Item menu_view_element_types[] = {
{"Points", 0, 0, 0, FL_MENU_TOGGLE},
{"Lines", 0, 0, 0, FL_MENU_TOGGLE},
{"Triangles", 0, 0, 0, FL_MENU_TOGGLE},
{"Quadrangles", 0, 0, 0, FL_MENU_TOGGLE},
{"Tetrahedra", 0, 0, 0, FL_MENU_TOGGLE},
{"Hexahedra", 0, 0, 0, FL_MENU_TOGGLE},
{"Prisms", 0, 0, 0, FL_MENU_TOGGLE},
{"Pyramids", 0, 0, 0, FL_MENU_TOGGLE},
{0}
};
view_menu_butt[1] = new Fl_Menu_Button(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Elements");
view_menu_butt[1]->menu(menu_view_element_types);
view_menu_butt[1]->callback(view_options_ok_cb);
static Fl_Menu_Item menu_boundary[] = {
{"None", 0, 0, 0},
{"Dimension - 1", 0, 0, 0},
{"Dimension - 2", 0, 0, 0},
{"Dimension - 3", 0, 0, 0},
{0}
};
view_choice[9] = new Fl_Choice(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Element boundary mode");
view_choice[9]->menu(menu_boundary);
view_choice[9]->align(FL_ALIGN_RIGHT);
view_choice[9]->callback(view_options_ok_cb);
view_value[0] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 7 * BH, IW, BH, "Normals");
view_value[0]->minimum(0);
view_value[0]->maximum(500);
view_value[0]->step(1);
view_value[0]->align(FL_ALIGN_RIGHT);
view_value[0]->when(FL_WHEN_RELEASE);
view_value[0]->callback(view_options_ok_cb);
view_value[1] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 8 * BH, IW, BH, "Tangents");
view_value[1]->minimum(0);
view_value[1]->maximum(500);
view_value[1]->step(1);
view_value[1]->align(FL_ALIGN_RIGHT);
view_value[1]->when(FL_WHEN_RELEASE);
view_value[1]->callback(view_options_ok_cb);
static Fl_Menu_Item menu_view_field_types[] = {
{"Scalar", 0, 0, 0, FL_MENU_TOGGLE},
{"Vector", 0, 0, 0, FL_MENU_TOGGLE},
{"Tensor", 0, 0, 0, FL_MENU_TOGGLE},
{0}
};
view_menu_butt[0] = new Fl_Menu_Button(L + 2 * WB, 2 * WB + 9 * BH, IW, BH, "Fields");
view_menu_butt[0]->menu(menu_view_field_types);
view_menu_butt[0]->callback(view_options_ok_cb);
view_value[33] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 10 * BH, IW, BH, "Maximum recursion level");
view_value[33]->align(FL_ALIGN_RIGHT);
view_value[33]->minimum(0);
view_value[33]->maximum(MAX_LEVEL_OF_ZOOM);
view_value[33]->step(1);
view_value[33]->value(0);
view_value[33]->when(FL_WHEN_RELEASE);
view_value[33]->callback(view_options_ok_cb);
view_value[34] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 11 * BH, IW, BH, "Target error");
view_value[34]->align(FL_ALIGN_RIGHT);
view_value[34]->minimum(0);
view_value[34]->maximum(1);
view_value[34]->value(1.e-2);
view_value[34]->when(FL_WHEN_RELEASE);
view_value[34]->callback(view_options_ok_cb);
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Offset");
o->hide();
Fl_Box *b = new Fl_Box(FL_NO_BOX, L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Coordinate transformation:");
b->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT);
int ss = 2*IW/3/3+4;
view_value[51] = new Fl_Value_Input(L + 2 * WB , 2 * WB + 2 * BH, ss, BH);
view_value[52] = new Fl_Value_Input(L + 2 * WB + ss , 2 * WB + 2 * BH, ss, BH);
view_value[53] = new Fl_Value_Input(L + 2 * WB + 2*ss, 2 * WB + 2 * BH, ss, BH, " X");
view_value[40] = new Fl_Value_Input(L + 2 * WB + IW , 2 * WB + 2 * BH, 7*IW/10, BH);
view_value[54] = new Fl_Value_Input(L + 2 * WB , 2 * WB + 3 * BH, ss, BH);
view_value[55] = new Fl_Value_Input(L + 2 * WB + ss , 2 * WB + 3 * BH, ss, BH);
view_value[56] = new Fl_Value_Input(L + 2 * WB + 2*ss, 2 * WB + 3 * BH, ss, BH, " Y +");
view_value[41] = new Fl_Value_Input(L + 2 * WB + IW , 2 * WB + 3 * BH, 7*IW/10, BH);
view_value[57] = new Fl_Value_Input(L + 2 * WB , 2 * WB + 4 * BH, ss, BH);
view_value[58] = new Fl_Value_Input(L + 2 * WB + ss , 2 * WB + 4 * BH, ss, BH);
view_value[59] = new Fl_Value_Input(L + 2 * WB + 2*ss, 2 * WB + 4 * BH, ss, BH, " Z");
view_value[42] = new Fl_Value_Input(L + 2 * WB + IW , 2 * WB + 4 * BH, 7*IW/10, BH);
Fl_Box *b2 = new Fl_Box(FL_NO_BOX, L + 2 * WB + 2 * IW-WB, 2 * WB + 1 * BH, 7*IW/10, BH, "Raise:");
b2->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT);
view_value[43] = new Fl_Value_Input(L + 2 * WB + 2 * IW-WB, 2 * WB + 2 * BH, 7*IW/10, BH, "X");
view_value[44] = new Fl_Value_Input(L + 2 * WB + 2 * IW-WB, 2 * WB + 3 * BH, 7*IW/10, BH, "Y");
view_value[45] = new Fl_Value_Input(L + 2 * WB + 2 * IW-WB, 2 * WB + 4 * BH, 7*IW/10, BH, "Z");
for(int i = 40; i <= 45; i++){
view_value[i]->align(FL_ALIGN_RIGHT);
view_value[i]->when(FL_WHEN_RELEASE);
view_value[i]->callback(view_options_ok_cb);
}
for(int i = 51; i <= 59; i++){
view_value[i]->minimum(-1.);
view_value[i]->maximum(1.);
view_value[i]->step(0.1);
view_value[i]->align(FL_ALIGN_RIGHT);
view_value[i]->when(FL_WHEN_RELEASE);
view_value[i]->callback(view_options_ok_cb);
}
view_butt[6] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 5 * BH, BW, BH, "Use general transformation expressions");
view_butt[6]->type(FL_TOGGLE_BUTTON);
view_butt[6]->callback(view_options_ok_cb, (void*)"general_transform");
view_choice[11] = new Fl_Choice(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Data source");
view_choice[11]->align(FL_ALIGN_RIGHT);
view_choice[11]->add("Self");
view_choice[11]->callback(view_options_ok_cb);
view_value[2] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 7 * BH, IW, BH, "Factor");
view_value[2]->align(FL_ALIGN_RIGHT);
view_value[2]->when(FL_WHEN_RELEASE);
view_value[2]->callback(view_options_ok_cb);
view_input[4] = new Fl_Input(L + 2 * WB, 2 * WB + 8 * BH, IW, BH, "X expression");
view_input[4]->align(FL_ALIGN_RIGHT);
view_input[4]->callback(view_options_ok_cb);
view_input[5] = new Fl_Input(L + 2 * WB, 2 * WB + 9 * BH, IW, BH, "Y expression");
view_input[5]->align(FL_ALIGN_RIGHT);
view_input[5]->callback(view_options_ok_cb);
view_input[6] = new Fl_Input(L + 2 * WB, 2 * WB + 10 * BH, IW, BH, "Z expression");
view_input[6]->align(FL_ALIGN_RIGHT);
view_input[6]->callback(view_options_ok_cb);
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Aspect");
o->hide();
view_value[12] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Element shrinking factor");
view_value[12]->minimum(0.);
view_value[12]->step(0.01);
view_value[12]->maximum(1.);
view_value[12]->align(FL_ALIGN_RIGHT);
view_value[12]->when(FL_WHEN_RELEASE);
view_value[12]->callback(view_options_ok_cb);
view_choice[5] = new Fl_Choice(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Point display");
view_choice[5]->menu(menu_point_display);
view_choice[5]->align(FL_ALIGN_RIGHT);
view_choice[5]->callback(view_options_ok_cb);
view_value[61] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 3 * BH, IW, BH, "Point size");
view_value[61]->minimum(0.1);
view_value[61]->maximum(50);
view_value[61]->step(0.1);
view_value[61]->align(FL_ALIGN_RIGHT);
view_value[61]->callback(view_options_ok_cb);
view_choice[6] = new Fl_Choice(L + 2 * WB, 2 * WB + 4 * BH, IW, BH, "Line display");
view_choice[6]->menu(menu_line_display);
view_choice[6]->align(FL_ALIGN_RIGHT);
view_choice[6]->callback(view_options_ok_cb);
view_value[62] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Line width");
view_value[62]->minimum(0.1);
view_value[62]->maximum(50);
view_value[62]->step(0.1);
view_value[62]->align(FL_ALIGN_RIGHT);
view_value[62]->callback(view_options_ok_cb);
{
view_vector = new Fl_Group(L + 2 * WB, 2 * WB + 6 * BH, width - 2 * WB, 4 * BH, 0);
static Fl_Menu_Item menu_vectype[] = {
{"Line", 0, 0, 0},
{"Arrow", 0, 0, 0},
{"Pyramid", 0, 0, 0},
{"3D arrow", 0, 0, 0},
{"Displacement", 0, 0, 0},
{0}
};
view_choice[2] = new Fl_Choice(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Vector display");
view_choice[2]->menu(menu_vectype);
view_choice[2]->align(FL_ALIGN_RIGHT);
view_choice[2]->callback(view_options_ok_cb);
view_push_butt[0] = new Fl_Button(L + 2 * IW - 2 * WB, 2 * WB + 6 * BH, (int)(1.5*BB), BH, "Edit arrow shape");
view_push_butt[0]->callback(view_arrow_param_cb);
view_value[60] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 7 * BH, IW, BH, "Arrow size");
view_value[60]->minimum(0);
view_value[60]->maximum(500);
view_value[60]->step(1);
view_value[60]->align(FL_ALIGN_RIGHT);
view_value[60]->callback(view_options_ok_cb);
view_butt[0] = new Fl_Check_Button(L + 2 * IW - 2 * WB, 2 * WB + 7 * BH, (int)(1.5*BB), BH, "Proportional");
view_butt[0]->type(FL_TOGGLE_BUTTON);
view_butt[0]->callback(view_options_ok_cb);
view_value[63] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 8 * BH, IW, BH, "Displacement factor");
view_value[63]->minimum(0.);
view_value[63]->maximum(1.);
view_value[63]->step(0.01);
view_value[63]->align(FL_ALIGN_RIGHT);
view_value[63]->when(FL_WHEN_RELEASE);
view_value[63]->callback(view_options_ok_cb);
view_choice[10] = new Fl_Choice(L + 2 * WB, 2 * WB + 9 * BH, IW, BH, "Data source");
view_choice[10]->align(FL_ALIGN_RIGHT);
view_choice[10]->add("Self");
view_choice[10]->callback(view_options_ok_cb);
view_vector->end();
}
static Fl_Menu_Item menu_vecloc[] = {
{"Barycenter", 0, 0, 0},
{"Vertex", 0, 0, 0},
{0}
};
view_choice[3] = new Fl_Choice(L + 2 * WB, 2 * WB + 10 * BH, IW, BH, "Glyph location");
view_choice[3]->menu(menu_vecloc);
view_choice[3]->align(FL_ALIGN_RIGHT);
view_choice[3]->callback(view_options_ok_cb);
static Fl_Menu_Item menu_tensor[] = {
{"Von-Mises", 0, 0, 0},
{"LMGC90", 0, 0, 0},
{"LMGC90 Type", 0, 0, 0},
{"LMGC90 Coordinance", 0, 0, 0},
{"LMGC90 Pression", 0, 0, 0},
{"LMGC90 Normal stress", 0, 0, 0},
{"LMGC90 X displacement", 0, 0, 0},
{"LMGC90 Y displacement", 0, 0, 0},
{"LMGC90 Z displacement", 0, 0, 0},
{"LMGC90 Average displacement", 0, 0, 0},
{"LMGC90 Norm of displacement", 0, 0, 0},
{0}
};
view_choice[4] = new Fl_Choice(L + 2 * WB, 2 * WB + 11 * BH, IW, BH, "Tensor display");
view_choice[4]->menu(menu_tensor);
view_choice[4]->align(FL_ALIGN_RIGHT);
view_choice[4]->callback(view_options_ok_cb);
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Light");
o->hide();
view_butt[11] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 1 * BH, BW, BH, "Enable lighting");
view_butt[11]->tooltip("(Alt+w)");
view_butt[11]->type(FL_TOGGLE_BUTTON);
view_butt[11]->callback(view_options_ok_cb, (void*)"view_light");
view_butt[8] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 2 * BH, BW, BH, "Enable lighting of lines");
view_butt[8]->type(FL_TOGGLE_BUTTON);
view_butt[8]->callback(view_options_ok_cb);
view_butt[9] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW, BH, "Use two-side lighting");
view_butt[9]->type(FL_TOGGLE_BUTTON);
view_butt[9]->callback(view_options_ok_cb);
view_butt[12] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Smooth normals");
view_butt[12]->type(FL_TOGGLE_BUTTON);
view_butt[12]->callback(view_options_ok_cb);
view_value[10] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Smoothing threshold angle");
view_value[10]->minimum(0.);
view_value[10]->step(1.);
view_value[10]->maximum(180.);
view_value[10]->align(FL_ALIGN_RIGHT);
view_value[10]->when(FL_WHEN_RELEASE);
view_value[10]->callback(view_options_ok_cb);
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Color");
o->hide();
view_butt[24] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 1 * BH, BW, BH, "Use fake transparency mode");
view_butt[24]->type(FL_TOGGLE_BUTTON);
view_butt[24]->callback(view_options_ok_cb);
view_butt[26] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 2 * BH, BW, BH, "Stipple curves in 2D plots");
view_butt[26]->type(FL_TOGGLE_BUTTON);
view_butt[26]->callback(view_options_ok_cb);
Fl_Scroll *s = new Fl_Scroll(L + 2 * WB, 3 * WB + 3 * BH, IW + 20, height - 5 * WB - 3 * BH);
int i = 0;
while(ViewOptions_Color[i].str) {
view_col[i] = new Fl_Button(L + 2 * WB, 3 * WB + (3 + i) * BH, IW, BH, ViewOptions_Color[i].str);
view_col[i]->callback(view_color_cb, (void *)ViewOptions_Color[i].function);
i++;
}
s->end();
o->end();
}
{
Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Map");
o->hide();
view_colorbar_window = new Colorbar_Window(L + 2 * WB, 2 * WB + BH, width - 4 * WB, height - 4 * WB - BH);
view_colorbar_window->end();
view_colorbar_window->callback(view_options_ok_cb);
o->end();
}
o->end();
}
view_group->end();
opt_window->position(CTX.opt_position[0], CTX.opt_position[1]);
opt_window->end();
}
void GUI::update_view_window(int num)
{
if(num < 0 || num >= List_Nbr(CTX.post.list))
return;
view_number = num;
Post_View *v = *(Post_View **) List_Pointer(CTX.post.list, num);
double maxval = MAX(fabs(v->Min), fabs(v->Max));
if(!maxval) maxval = 1.;
double val1 = 10. * CTX.lc;
double val2 = 2. * CTX.lc / maxval;
opt_view_name(num, GMSH_GUI, NULL);
opt_view_format(num, GMSH_GUI, NULL);
opt_view_type(num, GMSH_GUI, 0);
opt_view_show_scale(num, GMSH_GUI, 0);
opt_view_draw_strings(num, GMSH_GUI, 0);
opt_view_max_recursion_level (num, GMSH_GUI, 0);
opt_view_target_error (num, GMSH_GUI, 0);
if(v->adaptive){
view_value[33]->activate();
view_value[34]->activate();
}
else{
view_value[33]->deactivate();
view_value[34]->deactivate();
}
if(v->NbSP) {
((Fl_Menu_Item*)view_choice[13]->menu())[1].activate();
((Fl_Menu_Item*)view_choice[13]->menu())[2].activate();
}
else {
((Fl_Menu_Item*)view_choice[13]->menu())[1].deactivate();
((Fl_Menu_Item*)view_choice[13]->menu())[2].deactivate();
}
opt_view_auto_position(num, GMSH_GUI, 0);
opt_view_position0(num, GMSH_GUI, 0);
opt_view_position1(num, GMSH_GUI, 0);
opt_view_size0(num, GMSH_GUI, 0);
opt_view_size1(num, GMSH_GUI, 0);
opt_view_axes(num, GMSH_GUI, 0);
opt_view_axes_format0(num, GMSH_GUI, NULL);
opt_view_axes_format1(num, GMSH_GUI, NULL);
opt_view_axes_format2(num, GMSH_GUI, NULL);
opt_view_axes_tics0(num, GMSH_GUI, 0);
opt_view_axes_tics1(num, GMSH_GUI, 0);
opt_view_axes_tics2(num, GMSH_GUI, 0);
opt_view_axes_label0(num, GMSH_GUI, NULL);
opt_view_axes_label1(num, GMSH_GUI, NULL);
opt_view_axes_label2(num, GMSH_GUI, NULL);
opt_view_axes_auto_position(num, GMSH_GUI, 0);
opt_view_axes_xmin(num, GMSH_GUI, 0);
opt_view_axes_xmax(num, GMSH_GUI, 0);
opt_view_axes_ymin(num, GMSH_GUI, 0);
opt_view_axes_ymax(num, GMSH_GUI, 0);
opt_view_axes_zmin(num, GMSH_GUI, 0);
opt_view_axes_zmax(num, GMSH_GUI, 0);
for(int i = 13; i <= 18; i++){
view_value[i]->step(CTX.lc/200.);
view_value[i]->minimum(-CTX.lc);
view_value[i]->maximum(CTX.lc);
}
if(v->TextOnly) {
view_range->deactivate();
((Fl_Menu_Item*)view_choice[13]->menu())[0].deactivate();
}
else {
view_range->activate();
((Fl_Menu_Item*)view_choice[13]->menu())[0].activate();
}
opt_view_show_element(num, GMSH_GUI, 0);
opt_view_light(num, GMSH_GUI, 0);
opt_view_light_two_side(num, GMSH_GUI, 0);
opt_view_light_lines(num, GMSH_GUI, 0);
opt_view_smooth_normals(num, GMSH_GUI, 0);
opt_view_angle_smooth_normals(num, GMSH_GUI, 0);
opt_view_boundary(num, GMSH_GUI, 0);
opt_view_explode(num, GMSH_GUI, 0);
opt_view_draw_points(num, GMSH_GUI, 0);
opt_view_draw_lines(num, GMSH_GUI, 0);
opt_view_draw_triangles(num, GMSH_GUI, 0);
opt_view_draw_quadrangles(num, GMSH_GUI, 0);
opt_view_draw_tetrahedra(num, GMSH_GUI, 0);
opt_view_draw_hexahedra(num, GMSH_GUI, 0);
opt_view_draw_prisms(num, GMSH_GUI, 0);
opt_view_draw_pyramids(num, GMSH_GUI, 0);
opt_view_draw_scalars(num, GMSH_GUI, 0);
opt_view_draw_vectors(num, GMSH_GUI, 0);
opt_view_draw_tensors(num, GMSH_GUI, 0);
opt_view_normals(num, GMSH_GUI, 0);
opt_view_tangents(num, GMSH_GUI, 0);
opt_view_nb_iso(num, GMSH_GUI, 0);
opt_view_intervals_type(num, GMSH_GUI, 0);
opt_view_range_type(num, GMSH_GUI, 0);
opt_view_custom_min(num, GMSH_GUI, 0);
opt_view_custom_max(num, GMSH_GUI, 0);
opt_view_scale_type(num, GMSH_GUI, 0);
opt_view_saturate_values(num, GMSH_GUI, 0);
opt_view_offset0(num, GMSH_GUI, 0);
opt_view_offset1(num, GMSH_GUI, 0);
opt_view_offset2(num, GMSH_GUI, 0);
for(int i = 40; i <= 42; i++) {
view_value[i]->step(val1/100.);
view_value[i]->minimum(-val1);
view_value[i]->maximum(val1);
}
opt_view_transform00(num, GMSH_GUI, 0);
opt_view_transform01(num, GMSH_GUI, 0);
opt_view_transform02(num, GMSH_GUI, 0);
opt_view_transform10(num, GMSH_GUI, 0);
opt_view_transform11(num, GMSH_GUI, 0);
opt_view_transform12(num, GMSH_GUI, 0);
opt_view_transform20(num, GMSH_GUI, 0);
opt_view_transform21(num, GMSH_GUI, 0);
opt_view_transform22(num, GMSH_GUI, 0);
opt_view_raise0(num, GMSH_GUI, 0);
opt_view_raise1(num, GMSH_GUI, 0);
opt_view_raise2(num, GMSH_GUI, 0);
for(int i = 43; i <= 45; i++) {
view_value[i]->step(val2/100.);
view_value[i]->minimum(-val2);
view_value[i]->maximum(val2);
}
opt_view_use_gen_raise(num, GMSH_GUI, 0);
opt_view_gen_raise_view(num, GMSH_GUI, 0);
opt_view_gen_raise_factor(num, GMSH_GUI, 0);
opt_view_gen_raise0(num, GMSH_GUI, 0);
opt_view_gen_raise1(num, GMSH_GUI, 0);
opt_view_gen_raise2(num, GMSH_GUI, 0);
view_value[2]->step(val2/100.);
view_value[2]->minimum(-val2);
view_value[2]->maximum(val2);
if(v->NbTimeStep == 1) {
view_value[50]->deactivate();
view_butt_rep[0]->deactivate();
view_butt_rep[1]->deactivate();
}
else {
view_value[50]->activate();
view_butt_rep[0]->activate();
view_butt_rep[1]->activate();
}
view_value[50]->maximum(v->NbTimeStep - 1);
opt_view_timestep(num, GMSH_GUI, 0);
opt_view_show_time(num, GMSH_GUI, 0);
if(v->ScalarOnly)
view_vector->deactivate();
else
view_vector->activate();
opt_view_point_size(num, GMSH_GUI, 0);
opt_view_point_type(num, GMSH_GUI, 0);
opt_view_line_width(num, GMSH_GUI, 0);
opt_view_line_type(num, GMSH_GUI, 0);
opt_view_vector_type(num, GMSH_GUI, 0);
opt_view_arrow_size(num, GMSH_GUI, 0);
opt_view_arrow_size_proportional(num, GMSH_GUI, 0);
opt_view_displacement_factor(num, GMSH_GUI, 0);
double val3 = 2. * CTX.lc / maxval;
view_value[63]->step(val3/100.);
view_value[63]->maximum(val3);
opt_view_external_view(num, GMSH_GUI, 0);
opt_view_glyph_location(num, GMSH_GUI, 0);
opt_view_tensor_type(num, GMSH_GUI, 0);
opt_view_fake_transparency(num, GMSH_GUI, 0);
opt_view_use_stipple(num, GMSH_GUI, 0);
opt_view_color_points(num, GMSH_GUI, 0);
opt_view_color_lines(num, GMSH_GUI, 0);
opt_view_color_triangles(num, GMSH_GUI, 0);
opt_view_color_quadrangles(num, GMSH_GUI, 0);
opt_view_color_tetrahedra(num, GMSH_GUI, 0);
opt_view_color_hexahedra(num, GMSH_GUI, 0);
opt_view_color_prisms(num, GMSH_GUI, 0);
opt_view_color_pyramids(num, GMSH_GUI, 0);
opt_view_color_tangents(num, GMSH_GUI, 0);
opt_view_color_normals(num, GMSH_GUI, 0);
opt_view_color_text2d(num, GMSH_GUI, 0);
opt_view_color_text3d(num, GMSH_GUI, 0);
opt_view_color_axes(num, GMSH_GUI, 0);
view_colorbar_window->update(v->Name, v->Min, v->Max, &v->CT, &v->Changed);
}
// Create the plugin manager window
void GUI::create_plugin_dialog_box(GMSH_Plugin *p, int x, int y, int width, int height)
{
p->dialogBox = new PluginDialogBox;
p->dialogBox->group = new Fl_Group(x, y, width, height);
{
Fl_Tabs *o = new Fl_Tabs(x, y, width, height);
{
Fl_Group *g = new Fl_Group(x, y + BH, width, height - BH, "Options");
Fl_Scroll *s = new Fl_Scroll(x + WB, y + WB + BH, width - 2 * WB, height - BH - 2 * WB);
int m = p->getNbOptionsStr();
if(m > MAX_PLUGIN_OPTIONS) m = MAX_PLUGIN_OPTIONS;
int n = p->getNbOptions();
if(n > MAX_PLUGIN_OPTIONS) n = MAX_PLUGIN_OPTIONS;
int k = 0;
for(int i = 0; i < m; i++) {
StringXString *sxs = p->getOptionStr(i);
p->dialogBox->input[i] = new Fl_Input(x + WB, y + WB + (k + 1) * BH, IW, BH, sxs->str);
p->dialogBox->input[i]->align(FL_ALIGN_RIGHT);
p->dialogBox->input[i]->value(sxs->def);
k++;
}
for(int i = 0; i < n; i++) {
StringXNumber *sxn = p->getOption(i);
p->dialogBox->value[i] = new Fl_Value_Input(x + WB, y + WB + (k + 1) * BH, IW, BH, sxn->str);
p->dialogBox->value[i]->align(FL_ALIGN_RIGHT);
p->dialogBox->value[i]->value(sxn->def);
k++;
}
s->end();
g->end();
o->resizable(g); // to avoid ugly resizing of tab labels
}
{
Fl_Group *g = new Fl_Group(x, y + BH, width, height - BH, "About");
Fl_Browser *o = new Fl_Browser(x + WB, y + WB + BH, width - 2 * WB, height - 2 * WB - BH);
char name[1024], copyright[256], author[256], help[4096];
p->getName(name);
p->getInfos(author, copyright, help);
o->add(" ");
add_multiline_in_browser(o, "@c@b@.", name);
o->add(" ");
add_multiline_in_browser(o, "", help);
o->add(" ");
add_multiline_in_browser(o, "Author: ", author);
add_multiline_in_browser(o, "Copyright (C) ", copyright);
o->add(" ");
g->end();
}
o->end();
}
p->dialogBox->group->end();
p->dialogBox->group->hide();
}
void GUI::reset_plugin_view_browser()
{
// save selected state
std::vector<int> state;
for(int i = 0; i < plugin_view_browser->size(); i++){
if(plugin_view_browser->selected(i + 1))
state.push_back(1);
else
state.push_back(0);
}
char str[128];
plugin_view_browser->clear();
if(List_Nbr(CTX.post.list)){
plugin_view_browser->activate();
for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
sprintf(str, "View [%d]", i);
plugin_view_browser->add(str);
}
for(int i = 0; i < plugin_view_browser->size(); i++){
if(i < state.size() && state[i])
plugin_view_browser->select(i + 1);
}
}
else{
plugin_view_browser->add("No Views");
plugin_view_browser->deactivate();
}
view_plugin_browser_cb(NULL, NULL);
}
void GUI::create_plugin_window(int numview)
{
int width0 = 40 * fontsize;
int height0 = 13 * BH + 5 * WB;
int width = (CTX.plugin_size[0] < width0) ? width0 : CTX.plugin_size[0];
int height = (CTX.plugin_size[1] < height0) ? height0 : CTX.plugin_size[1];
if(plugin_window) {
reset_plugin_view_browser();
if(numview >= 0 && numview < List_Nbr(CTX.post.list)){
plugin_view_browser->deselect();
plugin_view_browser->select(numview + 1);
view_plugin_browser_cb(NULL, NULL);
}
plugin_window->show();
return;
}
plugin_window = new Dialog_Window(width, height, "Plugins");
plugin_window->box(GMSH_WINDOW_BOX);
{
Fl_Button *o = new Fl_Button(width - BB - WB, height - BH - WB, BB, BH, "Cancel");
o->callback(view_plugin_cancel_cb);
}
{
plugin_run = new Fl_Return_Button(width - 2 * BB - 2 * WB, height - BH - WB, BB, BH, "Run");
plugin_run->callback(view_plugin_run_cb);
plugin_run->deactivate();
}
int L1 = width / 4, L2 = 2 * L1 / 3;
plugin_browser = new Fl_Hold_Browser(WB, WB, L1, height - 3 * WB - BH);
plugin_browser->callback(view_plugin_browser_cb);
plugin_view_browser = new Fl_Multi_Browser(WB + L1, WB, L2, height - 3 * WB - BH);
plugin_view_browser->has_scrollbar(Fl_Browser_::VERTICAL);
plugin_view_browser->callback(view_plugin_browser_cb);
for(GMSH_PluginManager::iter it = GMSH_PluginManager::instance()->begin();
it != GMSH_PluginManager::instance()->end(); ++it) {
GMSH_Plugin *p = (*it).second;
if(p->getType() == GMSH_Plugin::GMSH_POST_PLUGIN) {
char name[256];
p->getName(name);
plugin_browser->add(name, p);
create_plugin_dialog_box(p, 2 * WB + L1 + L2, WB, width - L1 - L2 - 3 * WB, height - 3 * WB - BH);
// select first plugin by default
if(it == GMSH_PluginManager::instance()->begin()){
plugin_browser->select(1);
p->dialogBox->group->show();
}
}
}
Dummy_Box *resize_box = new Dummy_Box(WB + L1 / 2, WB, width - L1 / 2- 2 * BB - 3 * WB, height - 3 * WB - BH);
plugin_window->resizable(resize_box);
plugin_window->size_range(width0, height0);
plugin_window->position(CTX.plugin_position[0], CTX.plugin_position[1]);
plugin_window->end();
}
// Create the window for the statistics
void GUI::create_statistics_window()
{
int i, num = 0;
static Fl_Group *g[10];
if(stat_window) {
if(!stat_window->shown())
set_statistics(false);
for(i = 0; i < 3; i++)
g[i]->hide();
switch(get_context()){
case 0: g[0]->show(); break; // geometry
case 1: g[1]->show(); break; // mesh
case 3: g[2]->show(); break; // post-pro
default: g[1]->show(); break; // mesh
}
stat_window->show();
return;
}
int width = 26 * fontsize;
int height = 5 * WB + 17 * BH;
stat_window = new Dialog_Window(width, height, "Statistics");
stat_window->box(GMSH_WINDOW_BOX);
{
Fl_Tabs *o = new Fl_Tabs(WB, WB, width - 2 * WB, height - 3 * WB - BH);
{
g[0] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Geometry");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 1 * BH, IW, BH, "Points");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 2 * BH, IW, BH, "Lines");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 3 * BH, IW, BH, "Surfaces");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 4 * BH, IW, BH, "Volumes");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 5 * BH, IW, BH, "Physical groups");
g[0]->end();
}
{
g[1] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Mesh");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 1 * BH, IW, BH, "Nodes on Lines");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 2 * BH, IW, BH, "Nodes on surfaces");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 3 * BH, IW, BH, "Nodes in volumes");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 4 * BH, IW, BH, "Triangles");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 5 * BH, IW, BH, "Quadrangles");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 6 * BH, IW, BH, "Tetrahedra");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 7 * BH, IW, BH, "Hexahedra");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 8 * BH, IW, BH, "Prisms");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 9 * BH, IW, BH, "Pyramids");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 10 * BH, IW, BH, "Time for 1D mesh");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 11 * BH, IW, BH, "Time for 2D mesh");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 12 * BH, IW, BH, "Time for 3D mesh");
stat_value[num] = new Fl_Output(2 * WB, 2 * WB + 13 * BH, IW, BH, "Gamma");
stat_value[num]->tooltip("~ volume / sum_face_area / max_edge_length"); num++;
stat_value[num] = new Fl_Output(2 * WB, 2 * WB + 14 * BH, IW, BH, "Eta");
stat_value[num]->tooltip("~ volume^(2/3) / sum_edge_length^2"); num++;
stat_value[num] = new Fl_Output(2 * WB, 2 * WB + 15 * BH, IW, BH, "Rho");
stat_value[num]->tooltip("~ min_edge_length / max_edge_length"); num++;
stat_butt[0] = new Fl_Button(width - BB - 5 * WB, 2 * WB + 13 * BH, BB, BH, "Graph");
stat_butt[0]->callback(statistics_histogram_cb, (void *)"Gamma");
stat_butt[1] = new Fl_Button(width - BB - 5 * WB, 2 * WB + 14 * BH, BB, BH, "Graph");
stat_butt[1]->callback(statistics_histogram_cb, (void *)"Eta");
stat_butt[2] = new Fl_Button(width - BB - 5 * WB, 2 * WB + 15 * BH, BB, BH, "Graph");
stat_butt[2]->callback(statistics_histogram_cb, (void *)"Rho");
g[1]->end();
}
{
g[2] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Post-processing");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 1 * BH, IW, BH, "Views");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 2 * BH, IW, BH, "Visible points");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 3 * BH, IW, BH, "Visible lines");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 4 * BH, IW, BH, "Visible triangles");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 5 * BH, IW, BH, "Visible quadrangles");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 6 * BH, IW, BH, "Visible tetrahedra");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 7 * BH, IW, BH, "Visible hexahedra");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 8 * BH, IW, BH, "Visible prisms");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 9 * BH, IW, BH, "Visible pyramids");
stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 10 * BH, IW, BH, "Visible strings");
g[2]->end();
}
o->end();
}
for(i = 0; i < num; i++) {
stat_value[i]->align(FL_ALIGN_RIGHT);
stat_value[i]->value(0);
}
{
Fl_Return_Button *o = new Fl_Return_Button(width - 2 * BB - 2 * WB, height - BH - WB, BB, BH, "Update");
o->callback(statistics_update_cb);
}
{
Fl_Button *o = new Fl_Button(width - BB - WB, height - BH - WB, BB, BH, "Cancel");
o->callback(cancel_cb, (void *)stat_window);
}
stat_window->position(CTX.stat_position[0], CTX.stat_position[1]);
stat_window->end();
}
void GUI::set_statistics(bool compute_quality)
{
int num = 0;
static double s[50];
static char label[50][256];
if(compute_quality)
GetStatistics(s, quality);
else
GetStatistics(s);
// geom
sprintf(label[num], "%g", s[0]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g", s[1]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g", s[2]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g", s[3]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g", s[45]); stat_value[num]->value(label[num]); num++;
// mesh
sprintf(label[num], "%g", s[4]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g", s[5]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g", s[6]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g", s[7]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g", s[8]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g", s[9]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g", s[10]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g", s[11]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g", s[12]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g", s[13]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g", s[14]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g", s[15]); stat_value[num]->value(label[num]); num++;
if(!compute_quality){
for(int i = 0; i < 3; i++) stat_butt[i]->deactivate();
sprintf(label[num], "Press Update");
stat_value[num]->deactivate();
stat_value[num]->value(label[num]); num++;
sprintf(label[num], "Press Update");
stat_value[num]->deactivate();
stat_value[num]->value(label[num]); num++;
sprintf(label[num], "Press Update");
stat_value[num]->deactivate();
stat_value[num]->value(label[num]); num++;
}
else{
for(int i = 0; i < 3; i++) stat_butt[i]->activate();
sprintf(label[num], "%.4g (%.4g->%.4g)", s[17], s[18], s[19]);
stat_value[num]->activate();
stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%.4g (%.4g->%.4g)", s[20], s[21], s[22]);
stat_value[num]->activate();
stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%.4g (%.4g->%.4g)", s[23], s[24], s[25]);
stat_value[num]->activate();
stat_value[num]->value(label[num]); num++;
}
// post
sprintf(label[num], "%g", s[26]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g/%g", s[36], s[27]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g/%g", s[37], s[28]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g/%g", s[38], s[29]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g/%g", s[39], s[30]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g/%g", s[40], s[31]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g/%g", s[41], s[32]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g/%g", s[42], s[33]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g/%g", s[43], s[34]); stat_value[num]->value(label[num]); num++;
sprintf(label[num], "%g/%g", s[44], s[35]); stat_value[num]->value(label[num]); num++;
}
// Create the window for the messages
void GUI::create_message_window(bool redraw_only)
{
if(msg_window) {
if(msg_window->shown() && redraw_only)
msg_window->redraw();
else
msg_window->show();
return;
}
int width = CTX.msg_size[0];
int height = CTX.msg_size[1];
msg_window = new Dialog_Window(width, height, "Message Console");
msg_window->box(GMSH_WINDOW_BOX);
msg_browser = new Fl_Browser(WB, WB, width - 2 * WB, height - 3 * WB - BH);
msg_browser->textfont(FL_COURIER);
msg_browser->type(FL_MULTI_BROWSER);
msg_browser->callback(message_copy_cb);
{
Fl_Return_Button *o = new Fl_Return_Button(width - 3 * BB - 3 * WB, height - BH - WB, BB, BH, "Clear");
o->callback(message_clear_cb);
}
{
Fl_Button *o = new Fl_Button(width - 2 * BB - 2 * WB, height - BH - WB, BB, BH, "Save");
o->callback(message_save_cb);
}
{
Fl_Button *o = new Fl_Button(width - BB - WB, height - BH - WB, BB, BH, "Cancel");
o->callback(cancel_cb, (void *)msg_window);
}
msg_window->resizable(new Fl_Box(WB, WB, 100, 10));
msg_window->size_range(WB + 100 + 3 * BB + 4 * WB, 100);
msg_window->position(CTX.msg_position[0], CTX.msg_position[1]);
msg_window->end();
}
void GUI::add_message(char *msg)
{
for(int i = 0; i < (int)strlen(msg); i++)
if(msg[i] == '\n')
msg[i] = ' ';
msg_browser->add(msg, 0);
msg_browser->bottomline(msg_browser->size());
}
void GUI::save_message(char *filename)
{
FILE *fp;
if(!(fp = fopen(filename, "w"))) {
Msg(GERROR, "Unable to open file '%s'", filename);
return;
}
Msg(STATUS2, "Writing '%s'", filename);
for(int i = 1; i <= msg_browser->size(); i++) {
const char *c = msg_browser->text(i);
if(c[0] == '@')
fprintf(fp, "%s\n", &c[5]);
else
fprintf(fp, "%s\n", c);
}
Msg(STATUS2, "Wrote '%s'", filename);
fclose(fp);
}
void GUI::fatal_error(char *filename)
{
fl_alert("A fatal error has occurred which will force Gmsh to abort.\n"
"The error messages have been saved in the following file:\n\n%s",
filename);
}
// Create the visibility window
void GUI::reset_visibility()
{
if(vis_window) {
vis_browser->clear();
if(vis_window->shown())
visibility_cb(NULL, NULL);
}
}
class Vis_Browser : public Fl_Browser{
// special browser that reacts differently to Enter key
int handle(int event)
{
if(event == FL_KEYBOARD){
switch(Fl::event_key()) {
case FL_Enter:
case FL_KP_Enter:
visibility_ok_cb(NULL, NULL);
return 1;
}
}
return Fl_Browser::handle(event);
}
public:
Vis_Browser(int x, int y, int w , int h, const char* c = 0)
: Fl_Browser(x, y, w, h, c){}
};
void GUI::create_visibility_window(bool redraw_only)
{
if(vis_window) {
if(vis_window->shown() && redraw_only)
vis_window->redraw();
else
vis_window->show();
return;
}
static int cols[5] = { 15, 95, 95, 180, 0 };
static Fl_Menu_Item type_table[] = {
{"Elementary entities", 0, (Fl_Callback *) visibility_cb},
{"Physical groups", 0, (Fl_Callback *) visibility_cb},
{"Mesh partitions", 0, (Fl_Callback *) visibility_cb},
{0}
};
int width = cols[0] + cols[1] + cols[2] + cols[3] + 6 * WB;
int height = 18 * BH;
int brw = width - 4 * WB;
vis_window = new Dialog_Window(width, height, "Visibility");
vis_window->box(GMSH_WINDOW_BOX);
vis_type = new Fl_Choice(WB, WB, (width - 3 * WB) / 2, BH);
vis_type->menu(type_table);
vis_butt[0] = new Fl_Check_Button(WB + (width - 3 * WB) / 2 + WB, WB, (width - 3 * WB) / 2, BH,
"Set visibility recursively");
vis_butt[0]->type(FL_TOGGLE_BUTTON);
vis_butt[0]->value(1);
Fl_Tabs *o = new Fl_Tabs(WB, 2 * WB + BH, width - 2 * WB, height - 4 * WB - 2 * BH);
{
vis_group[0] = new Fl_Group(WB, 2 * WB + 2 * BH, width - 2 * WB, height - 4 * WB - 3 * BH, "Browser");
Fl_Button *o0 = new Fl_Button(2 * WB, 3 * WB + 2 * BH, cols[0], BH/2, "*");
o0->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE);
o0->tooltip("Select/unselect all");
o0->callback(visibility_sort_cb, (void *)"*");
Fl_Button *o1 = new Fl_Button(2 * WB, 3 * WB + 2 * BH + BH/2, cols[0], BH - BH/2, "-");
o1->tooltip("Invert selection");
o1->callback(visibility_sort_cb, (void *)"-");
Fl_Button *o2 = new Fl_Button(2 * WB + cols[0], 3 * WB + 2 * BH, cols[1], BH, "Type");
o2->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
o2->tooltip("Sort by type");
o2->callback(visibility_sort_cb, (void *)"type");
Fl_Button *o3 = new Fl_Button(2 * WB + cols[0] + cols[1], 3 * WB + 2 * BH, cols[2], BH, "Number");
o3->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
o3->tooltip("Sort by number");
o3->callback(visibility_sort_cb, (void *)"number");
Fl_Button *o4 = new Fl_Button(2 * WB + cols[0] + cols[1] + cols[2], 3 * WB + 2 * BH, cols[3], BH, "Name");
o4->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
o4->tooltip("Sort by name");
o4->callback(visibility_sort_cb, (void *)"name");
Fl_Button *o5 = new Fl_Button(width - 4 * WB, 3 * WB + 2 * BH, 2 * WB, BH, "+");
o5->tooltip("Add parameter name for first selected item");
o5->callback(visibility_sort_cb, (void *)"+");
{
Fl_Group *o = new Fl_Group(2 * WB, 3 * WB + 3 * BH, brw, height - 7 * WB - 5 * BH);
vis_browser = new Vis_Browser(2 * WB, 3 * WB + 3 * BH, brw, height - 7 * WB - 5 * BH);
vis_browser->type(FL_MULTI_BROWSER);
vis_browser->column_widths(cols);
o->end();
Fl_Group::current()->resizable(o);
}
vis_push_butt[0] = new Fl_Button(width - 2 * BB - 3 * WB, height - 2 * BH - 3 * WB, BB, BH, "Delete");
vis_push_butt[0]->callback(visibility_delete_cb);
Fl_Return_Button *b1 = new Fl_Return_Button(width - 1 * BB - 2 * WB, height - 2 * BH - 3 * WB, BB, BH, "Apply");
b1->callback(visibility_ok_cb);
vis_group[0]->end();
Fl_Group::current()->resizable(vis_group[0]);
}
{
vis_group[1] = new Fl_Group(WB, 2 * WB + 2 * BH, width - 2 * WB, height - 4 * WB - 2 * BH, "Numeric input");
vis_group[1]->resizable(NULL);
for(int i = 0; i < 6; i++){
vis_input[i] = new Fl_Input(width/2-WB/2-IW, 3 * WB + (i+2) * BH, IW, BH);
vis_input[i]->align(FL_ALIGN_LEFT);
vis_input[i]->value("*");
Fl_Button *o1 = new Fl_Button(width/2+WB/2, 3 * WB + (i+2) * BH, BB, BH, "Show");
o1->callback(visibility_number_cb, (void *)(100+i));
Fl_Button *o2 = new Fl_Button(width/2+WB/2+BB+WB, 3 * WB + (i+2) * BH, BB, BH, "Hide");
o2->callback(visibility_number_cb, (void *)i);
}
vis_input[0]->label("Node");
vis_input[0]->tooltip("Enter node number, or *");
vis_input[1]->label("Element");
vis_input[1]->tooltip("Enter element number, or *");
vis_input[2]->label("Point");
vis_input[2]->tooltip("Enter point number, or *");
vis_input[3]->label("Line");
vis_input[3]->tooltip("Enter line number, or *");
vis_input[4]->label("Surface");
vis_input[4]->tooltip("Enter surface number, or *");
vis_input[5]->label("Volume");
vis_input[5]->tooltip("Enter volume number, or *");
vis_group[1]->end();
}
{
vis_group[2] = new Fl_Group(WB, 2 * WB + 2 * BH, width - 2 * WB, height - 4 * WB - 2 * BH, "Interactive");
vis_group[2]->resizable(NULL);
int ll = width/2 - BH - WB - IW;
Fl_Box *b2 = new Fl_Box(FL_NO_BOX, ll, 3 * WB + 2 * BH, IW, BH,
"Hide with the mouse:");
b2->align(FL_ALIGN_INSIDE|FL_ALIGN_CENTER);
Fl_Button *butt1 = new Fl_Button(ll, 3 * WB + 3 * BH, IW, BH, "Elements");
butt1->callback(visibility_interactive_cb, (void *)"hide_elements");
Fl_Button *butt2 = new Fl_Button(ll, 3 * WB + 4 * BH, IW, BH, "Points");
butt2->callback(visibility_interactive_cb, (void *)"hide_points");
Fl_Button *butt3 = new Fl_Button(ll, 3 * WB + 5 * BH, IW, BH, "Lines");
butt3->callback(visibility_interactive_cb, (void *)"hide_lines");
Fl_Button *butt4 = new Fl_Button(ll, 3 * WB + 6 * BH, IW, BH, "Surfaces");
butt4->callback(visibility_interactive_cb, (void *)"hide_surfaces");
Fl_Button *butt5 = new Fl_Button(ll, 3 * WB + 7 * BH, IW, BH, "Volumes");
butt5->callback(visibility_interactive_cb, (void *)"hide_volumes");
Fl_Button *butt6 = new Fl_Button(ll + IW + WB, 3 * WB + 3 * BH, 2 * BH, 5*BH, "Show\nAll");
butt6->callback(visibility_interactive_cb, (void *)"show_all");
int ll2 = ll + IW + WB + 2*BH + WB;
Fl_Box *b12 = new Fl_Box(FL_NO_BOX, ll2, 3 * WB + 2 * BH, IW, BH,
"Show with the mouse:");
b12->align(FL_ALIGN_INSIDE|FL_ALIGN_CENTER);
Fl_Button *butt11 = new Fl_Button(ll2, 3 * WB + 3 * BH, IW, BH, "Elements");
butt11->callback(visibility_interactive_cb, (void *)"show_elements");
Fl_Button *butt12 = new Fl_Button(ll2, 3 * WB + 4 * BH, IW, BH, "Points");
butt12->callback(visibility_interactive_cb, (void *)"show_points");
Fl_Button *butt13 = new Fl_Button(ll2, 3 * WB + 5 * BH, IW, BH, "Lines");
butt13->callback(visibility_interactive_cb, (void *)"show_lines");
Fl_Button *butt14 = new Fl_Button(ll2, 3 * WB + 6 * BH, IW, BH, "Surfaces");
butt14->callback(visibility_interactive_cb, (void *)"show_surfaces");
Fl_Button *butt15 = new Fl_Button(ll2, 3 * WB + 7 * BH, IW, BH, "Volumes");
butt15->callback(visibility_interactive_cb, (void *)"show_volumes");
vis_group[2]->end();
}
o->end();
vis_window->resizable(o);
vis_window->size_range(width, 9 * BH + 6 * WB, width);
{
Fl_Button *o1 = new Fl_Button(width - 2 * BB - 2 * WB, height - BH - WB, BB, BH, "Save");
o1->callback(visibility_save_cb);
Fl_Button *o2 = new Fl_Button(width - BB - WB, height - BH - WB, BB, BH, "Cancel");
o2->callback(cancel_cb, (void *)vis_window);
}
vis_window->position(CTX.vis_position[0], CTX.vis_position[1]);
vis_window->end();
}
// Create the clipping planes window
void GUI::reset_clip_browser()
{
char str[128];
clip_browser->clear();
clip_browser->add("Geometry");
clip_browser->add("Mesh");
for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
sprintf(str, "View [%d]", i);
clip_browser->add(str);
}
int idx = clip_choice->value();
clip_browser->deselect();
for(int i = 0; i < clip_browser->size(); i++)
if(CTX.clip[idx] & (1<<i))
clip_browser->select(i+1);
for(int i = 0; i < 4; i++)
clip_value[i]->value(CTX.clip_plane[idx][i]);
for(int i = 4; i < 7; i++)
clip_value[i]->value(0.);
for(int i = 7; i < 10; i++)
clip_value[i]->value(1.);
for(int i = 0; i < 3; i++) {
clip_value[i]->step(0.01);
clip_value[i]->minimum(-1.0);
clip_value[i]->maximum(1.0);
}
double val1 = 0;
for(int i = 0; i < 3; i++)
val1 = std::max(val1, std::max(fabs(CTX.min[i]), fabs(CTX.max[i])));
val1 *= 1.5;
for(int i = 3; i < 10; i++){
clip_value[i]->step(val1/200.);
clip_value[i]->minimum(-val1);
clip_value[i]->maximum(val1);
}
}
void GUI::create_clip_window()
{
if(clip_window) {
reset_clip_browser();
clip_window->show();
return;
}
static Fl_Menu_Item plane_number[] = {
{"Plane 0", 0, 0},
{"Plane 1", 0, 0},
{"Plane 2", 0, 0},
{"Plane 3", 0, 0},
{"Plane 4", 0, 0},
{"Plane 5", 0, 0},
{0}
};
int width = 3 * BB + 4 * WB;
int height = 8 * BH + 5 * WB;
int brw = 105;
int BW = width - brw - 3 * WB - 3 * fontsize;
clip_window = new Dialog_Window(width, height, "Clipping Planes");
clip_window->box(GMSH_WINDOW_BOX);
clip_browser = new Fl_Multi_Browser(1 * WB, 1 * WB, brw, height - BH - 3 * WB);
clip_browser->callback(clip_update_cb);
Fl_Tabs *o = new Fl_Tabs(2 * WB + brw, WB, width - 3 * WB - brw, height - 3 * WB - BH);
{
clip_group[0] = new Fl_Group(2 * WB + brw, WB + BH, width - 3 * WB - brw, height - 3 * WB - 2 * BH, "Planes");
int ii = fontsize;
Fl_Button *invert = new Fl_Button(3 * WB + brw, 2 * WB + 2 * BH, ii, 4*BH, "-");
invert->callback(clip_invert_cb);
invert->tooltip("Invert orientation");
clip_choice = new Fl_Choice(3 * WB + brw, 2 * WB + 1 * BH, BW, BH);
clip_choice->menu(plane_number);
clip_choice->callback(clip_num_cb);
clip_value[0] = new Fl_Value_Input(3 * WB + brw + ii, 2 * WB + 2 * BH, BW - ii, BH, "A");
clip_value[1] = new Fl_Value_Input(3 * WB + brw + ii, 2 * WB + 3 * BH, BW - ii, BH, "B");
clip_value[2] = new Fl_Value_Input(3 * WB + brw + ii, 2 * WB + 4 * BH, BW - ii, BH, "C");
clip_value[3] = new Fl_Value_Input(3 * WB + brw + ii, 2 * WB + 5 * BH, BW - ii, BH, "D");
for(int i = 0; i < 4; i++){
clip_value[i]->align(FL_ALIGN_RIGHT);
clip_value[i]->callback(clip_update_cb);
}
clip_group[0]->end();
}
{
clip_group[1] = new Fl_Group(2 * WB + brw, WB + BH, width - 3 * WB - brw, height - 3 * WB - 2 * BH, "Box");
clip_group[1]->hide();
clip_value[4] = new Fl_Value_Input(3 * WB + brw, 2 * WB + 1 * BH, BW, BH, "Cx");
clip_value[5] = new Fl_Value_Input(3 * WB + brw, 2 * WB + 2 * BH, BW, BH, "Cy");
clip_value[6] = new Fl_Value_Input(3 * WB + brw, 2 * WB + 3 * BH, BW, BH, "Cz");
clip_value[7] = new Fl_Value_Input(3 * WB + brw, 2 * WB + 4 * BH, BW, BH, "Wx");
clip_value[8] = new Fl_Value_Input(3 * WB + brw, 2 * WB + 5 * BH, BW, BH, "Wy");
clip_value[9] = new Fl_Value_Input(3 * WB + brw, 2 * WB + 6 * BH, BW, BH, "Wz");
for(int i = 4; i < 10; i++){
clip_value[i]->align(FL_ALIGN_RIGHT);
clip_value[i]->callback(clip_update_cb);
}
clip_group[1]->end();
}
o->callback(clip_reset_cb);
o->end();
reset_clip_browser();
{
Fl_Return_Button *o = new Fl_Return_Button(width - 3 * BB - 3 * WB, height - BH - WB, BB, BH, "Redraw");
o->callback(redraw_cb);
}
{
Fl_Button *o = new Fl_Button(width - 2 * BB - 2 * WB, height - BH - WB, BB, BH, "Reset");
o->callback(clip_reset_cb);
}
{
Fl_Button *o = new Fl_Button(width - BB - WB, height - BH - WB, BB, BH, "Cancel");
o->callback(cancel_cb, (void *)clip_window);
}
clip_window->position(CTX.clip_position[0], CTX.clip_position[1]);
clip_window->end();
}
// create the manipulator
void GUI::update_manip_window(int force)
{
if(force || manip_window->shown()){
double val1 = CTX.lc;
for(int i = 0; i < 3; i++){
manip_value[i]->value(CTX.r[i]);
manip_value[i]->minimum(-360.);
manip_value[i]->maximum(360.);
manip_value[i]->step(1.);
manip_value[i+3]->value(CTX.t[i]);
manip_value[i+3]->minimum(-val1);
manip_value[i+3]->maximum(val1);
manip_value[i+3]->step(val1/200.);
manip_value[i+6]->value(CTX.s[i]);
manip_value[i+6]->minimum(0.01);
manip_value[i+6]->maximum(100.);
manip_value[i+6]->step(0.01);
}
}
}
void GUI::create_manip_window()
{
if(manip_window) {
update_manip_window(1);
manip_window->show();
return;
}
int width = 4 * BB + 2 * WB;
int height = 5 * BH + 3 * WB;
manip_window = new Dialog_Window(width, height, "Manipulator");
manip_window->box(GMSH_WINDOW_BOX);
Fl_Box *top[3], *left[3];
top[0] = new Fl_Box(WB + 1 * BB, 1 * WB + 0 * BH, BB, BH, "X");
top[1] = new Fl_Box(WB + 2 * BB, 1 * WB + 0 * BH, BB, BH, "Y");
top[2] = new Fl_Box(WB + 3 * BB, 1 * WB + 0 * BH, BB, BH, "Z");
left[0] = new Fl_Box(WB + 0 * BB, 1 * WB + 1 * BH, BB, BH, "Rotation");
left[1] = new Fl_Box(WB + 0 * BB, 1 * WB + 2 * BH, BB, BH, "Translation");
left[2] = new Fl_Box(WB + 0 * BB, 1 * WB + 3 * BH, BB, BH, "Scale");
for(int i = 0; i < 3; i++){
top[i]->align(FL_ALIGN_INSIDE|FL_ALIGN_CENTER);
left[i]->align(FL_ALIGN_INSIDE|FL_ALIGN_CENTER);
}
manip_value[0] = new Fl_Value_Input(WB + 1 * BB, 1 * WB + 1 * BH, BB, BH);
manip_value[1] = new Fl_Value_Input(WB + 2 * BB, 1 * WB + 1 * BH, BB, BH);
manip_value[2] = new Fl_Value_Input(WB + 3 * BB, 1 * WB + 1 * BH, BB, BH);
manip_value[3] = new Fl_Value_Input(WB + 1 * BB, 1 * WB + 2 * BH, BB, BH);
manip_value[4] = new Fl_Value_Input(WB + 2 * BB, 1 * WB + 2 * BH, BB, BH);
manip_value[5] = new Fl_Value_Input(WB + 3 * BB, 1 * WB + 2 * BH, BB, BH);
manip_value[6] = new Fl_Value_Input(WB + 1 * BB, 1 * WB + 3 * BH, BB, BH);
manip_value[7] = new Fl_Value_Input(WB + 2 * BB, 1 * WB + 3 * BH, BB, BH);
manip_value[8] = new Fl_Value_Input(WB + 3 * BB, 1 * WB + 3 * BH, BB, BH);
for(int i = 0; i < 9; i++){
if(i < 3){
manip_value[i]->minimum(0.);
manip_value[i]->maximum(360.);
manip_value[i]->step(1.);
}
else if(i > 5){
manip_value[i]->minimum(0.1);
manip_value[i]->maximum(100.);
manip_value[i]->step(0.1);
}
manip_value[i]->align(FL_ALIGN_RIGHT);
manip_value[i]->callback(manip_update_cb);
}
{
Fl_Return_Button *o = new Fl_Return_Button(width - 2 * BB - 2 * WB, height - BH - WB, BB, BH, "Reset");
o->callback(status_xyz1p_cb, (void *)"reset");
}
{
Fl_Button *o = new Fl_Button(width - BB - WB, height - BH - WB, BB, BH, "Cancel");
o->callback(cancel_cb, (void *)manip_window);
}
manip_window->position(CTX.manip_position[0], CTX.manip_position[1]);
manip_window->end();
}
// Create the about window
void GUI::create_about_window()
{
char buffer[1024];
if(about_window) {
about_window->show();
return;
}
int width = 28 * fontsize;
int height = 15 * BH + BH/2;
about_window = new Dialog_Window(width, height, "About Gmsh");
about_window->box(GMSH_WINDOW_BOX);
{
Fl_Browser *o = new Fl_Browser(WB, WB, width - 2 * WB, height - 3 * WB - BH);
o->has_scrollbar(0); // no scrollbars
o->add(" ");
o->add("@c@b@.Gmsh");
o->add("@c@.A three-dimensional finite element mesh generator");
o->add("@c@.with built-in pre- and post-processing facilities");
o->add(" ");
o->add("@c@.Copyright (C) 1997-2007");
#if defined(__APPLE__)
o->add("@c@.Christophe Geuzaine and Jean-Francois Remacle");
#else
o->add("@c@.Christophe Geuzaine and Jean-Franois Remacle");
#endif
o->add(" ");
o->add("@c@.Please send all questions and bug reports to");
o->add("@c@b@.gmsh@geuz.org");
o->add(" ");
sprintf(buffer, "@c@.Version: %s", Get_GmshVersion());
o->add(buffer);
sprintf(buffer, "@c@.License: %s", Get_GmshShortLicense());
o->add(buffer);
sprintf(buffer, "@c@.Graphical user interface toolkit: FLTK %d.%d.%d",
FL_MAJOR_VERSION, FL_MINOR_VERSION, FL_PATCH_VERSION);
o->add(buffer);
sprintf(buffer, "@c@.Build OS: %s", Get_GmshBuildOS());
o->add(buffer);
sprintf(buffer, "@c@.Build date: %s", Get_GmshBuildDate());
o->add(buffer);
sprintf(buffer, "@c@.Build host: %s", Get_GmshBuildHost());
o->add(buffer);
{
char str1[1024];
strcpy(str1, Get_BuildOptions());
unsigned int len = 30;
if(strlen(str1) > len){
int split;
for(split = len - 1; split >= 0; split--){
if(str1[split] == ' '){
str1[split] = '\0';
break;
}
}
sprintf(buffer, "@c@.Build options: %s", str1);
o->add(buffer);
sprintf(buffer, "@c@.%s", &str1[split+1]);
o->add(buffer);
}
else{
sprintf(buffer, "@c@.Options: %s", str1);
o->add(buffer);
}
}
sprintf(buffer, "@c@.Packaged by: %s", Get_GmshPackager());
o->add(buffer);
o->add(" ");
o->add("@c@.Visit http://www.geuz.org/gmsh/ for more information");
o->add(" ");
o->callback(cancel_cb, (void *)about_window);
}
{
Fl_Button *o = new Fl_Button(width/2 - BB - WB/2, height - BH - WB, BB, BH, "License");
o->callback(help_license_cb);
}
{
Fl_Button *o = new Fl_Button(width/2 + WB/2, height - BH - WB, BB, BH, "Credits");
o->callback(help_credits_cb);
}
about_window->position(Fl::x() + Fl::w()/2 - width / 2,
Fl::y() + Fl::h()/2 - height / 2);
about_window->end();
}
// Create the window for geometry context dependant definitions
void GUI::create_geometry_context_window(int num)
{
static Fl_Group *g[10];
int i;
if(context_geometry_window) {
for(i = 0; i < 6; i++)
g[i]->hide();
g[num]->show();
context_geometry_window->show();
return;
}
int width = 31 * fontsize;
int height = 5 * WB + 9 * BH;
context_geometry_window = new Dialog_Window(width, height, "Contextual Geometry Definitions");
context_geometry_window->box(GMSH_WINDOW_BOX);
{
Fl_Tabs *o = new Fl_Tabs(WB, WB, width - 2 * WB, height - 3 * WB - BH);
// 0: Parameter
{
g[0] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Parameter");
context_geometry_input[0] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Name");
context_geometry_input[0]->value("lc");
context_geometry_input[1] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Value");
context_geometry_input[1]->value("0.1");
for(i = 0; i < 2; i++) {
context_geometry_input[i]->align(FL_ALIGN_RIGHT);
}
{
Fl_Return_Button *o = new Fl_Return_Button(width - BB - 2 * WB, 2 * WB + 7 * BH, BB, BH, "Add");
o->callback(con_geometry_define_parameter_cb);
}
g[0]->end();
}
// 1: Point
{
g[1] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Point");
context_geometry_input[2] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "X coordinate");
context_geometry_input[2]->value("0");
context_geometry_input[3] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Y coordinate");
context_geometry_input[3]->value("0");
context_geometry_input[4] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Z coordinate");
context_geometry_input[4]->value("0");
context_geometry_input[5] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Characteristic length");
context_geometry_input[5]->value("0.1");
for(i = 2; i < 6; i++) {
context_geometry_input[i]->align(FL_ALIGN_RIGHT);
}
context_geometry_value[0] = new Fl_Value_Input(2 * WB, 2 * WB + 5 * BH, IW/3, BH);
context_geometry_value[1] = new Fl_Value_Input(2 * WB + IW/3, 2 * WB + 5 * BH, IW/3, BH);
context_geometry_value[2] = new Fl_Value_Input(2 * WB + 2*IW/3, 2 * WB + 5 * BH, IW/3, BH, "Snapping grid spacing");
for(i = 0; i < 3; i++) {
context_geometry_value[i]->align(FL_ALIGN_RIGHT);
context_geometry_value[i]->callback(con_geometry_snap_cb);
}
{
Fl_Return_Button *o = new Fl_Return_Button(width - BB - 2 * WB, 2 * WB + 7 * BH, BB, BH, "Add");
o->callback(con_geometry_define_point_cb);
}
g[1]->end();
}
// 2: Translation
{
g[2] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Translation");
context_geometry_input[6] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "X component");
context_geometry_input[6]->value("0");
context_geometry_input[7] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Y component");
context_geometry_input[7]->value("0");
context_geometry_input[8] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Z component");
context_geometry_input[8]->value("1");
for(i = 6; i < 9; i++) {
context_geometry_input[i]->align(FL_ALIGN_RIGHT);
}
g[2]->end();
}
// 3: Rotation
{
g[3] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Rotation");
context_geometry_input[9] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "X coordinate of an axis point");
context_geometry_input[9]->value("0");
context_geometry_input[10] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Y coordinate of an axis point");
context_geometry_input[10]->value("0");
context_geometry_input[11] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Z coordinate of an axis point");
context_geometry_input[11]->value("0");
context_geometry_input[12] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "X component of axis direction");
context_geometry_input[12]->value("0");
context_geometry_input[13] = new Fl_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "Y component of axis direction");
context_geometry_input[13]->value("1");
context_geometry_input[14] = new Fl_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "Z component of axis direction");
context_geometry_input[14]->value("0");
context_geometry_input[15] = new Fl_Input(2 * WB, 2 * WB + 7 * BH, IW, BH, "Angle in radians");
context_geometry_input[15]->value("Pi/4");
for(i = 9; i < 16; i++) {
context_geometry_input[i]->align(FL_ALIGN_RIGHT);
}
g[3]->end();
}
// 4: Scale
{
g[4] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Scale");
context_geometry_input[16] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "X component of direction");
context_geometry_input[16]->value("0");
context_geometry_input[17] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Y component of direction");
context_geometry_input[17]->value("0");
context_geometry_input[18] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Z component of direction");
context_geometry_input[18]->value("0");
context_geometry_input[19] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Factor");
context_geometry_input[19]->value("0.5");
for(i = 16; i < 20; i++) {
context_geometry_input[i]->align(FL_ALIGN_RIGHT);
}
g[4]->end();
}
// 5: Symmetry
{
g[5] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Symmetry");
context_geometry_input[20] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "A");
context_geometry_input[20]->value("1");
context_geometry_input[21] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "B");
context_geometry_input[21]->value("0");
context_geometry_input[22] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "C");
context_geometry_input[22]->value("0");
context_geometry_input[23] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "D");
context_geometry_input[23]->value("1");
for(i = 20; i < 24; i++) {
context_geometry_input[i]->align(FL_ALIGN_RIGHT);
}
g[5]->end();
}
o->end();
}
{
Fl_Button *o = new Fl_Button(width - BB - WB, height - BH - WB, BB, BH, "Cancel");
o->callback(cancel_cb, (void *)context_geometry_window);
}
context_geometry_window->position(CTX.ctx_position[0], CTX.ctx_position[1]);
context_geometry_window->end();
}
// Create the window for physical context dependant definitions
void GUI::call_for_solver_plugin (int dim)
{
GMSH_Solve_Plugin *sp = GMSH_PluginManager::instance()->findSolverPlugin();
if (sp) {
sp->popupPropertiesForPhysicalEntity(dim);
}
}
// Create the window for mesh context dependant definitions
void GUI::create_mesh_context_window(int num)
{
static Fl_Group *g[10];
static Fl_Menu menu_transfinite_dir[] = {
{"Left", 0, 0, 0},
{"Right", 0, 0, 0},
{"Alternated", 0, 0, 0},
{0}
};
if(context_mesh_window) {
for(int i = 0; i < 3; i++)
g[i]->hide();
g[num]->show();
context_mesh_window->show();
return;
}
int width = 29 * fontsize;
int height = 5 * WB + 5 * BH;
context_mesh_window = new Dialog_Window(width, height, "Contextual Mesh Definitions");
context_mesh_window->box(GMSH_WINDOW_BOX);
{
Fl_Tabs *o = new Fl_Tabs(WB, WB, width - 2 * WB, height - 3 * WB - BH);
// 0: Characteristic length
{
g[0] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Characteristic Length");
context_mesh_input[0] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Value");
context_mesh_input[0]->value("0.1");
context_mesh_input[0]->align(FL_ALIGN_RIGHT);
g[0]->end();
}
// 1: Transfinite line
{
g[1] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Transfinite Line");
context_mesh_input[1] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Number of points");
context_mesh_input[1]->value("10");
context_mesh_input[2] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Parameter");
context_mesh_input[2]->value("1");
for(int i = 1; i < 3; i++) {
context_mesh_input[i]->align(FL_ALIGN_RIGHT);
}
static Fl_Menu_Item menu_trsf_mesh[] = {
{"Progression", 0, 0, 0},
{"Bump", 0, 0, 0},
{0}
};
context_mesh_choice[0] = new Fl_Choice(2 * WB, 2 * WB + 2 * BH, IW, BH, "Type");
context_mesh_choice[0]->menu(menu_trsf_mesh);
context_mesh_choice[0]->align(FL_ALIGN_RIGHT);
g[1]->end();
}
// 2: Transfinite surface
{
g[2] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Transfinite Surface");
context_mesh_choice[1] = new Fl_Choice(2 * WB, 2 * WB + 1 * BH, IW, BH, "Transfinite Arrangement");
context_mesh_choice[1]->menu(menu_transfinite_dir);
context_mesh_choice[1]->align(FL_ALIGN_RIGHT);
g[2]->end();
}
o->end();
}
{
Fl_Button *o = new Fl_Button(width - BB - WB, height - BH - WB, BB, BH, "Cancel");
o->callback(cancel_cb, (void *)context_mesh_window);
}
context_mesh_window->position(CTX.ctx_position[0], CTX.ctx_position[1]);
context_mesh_window->end();
}
// Create the windows for the solvers
void GUI::create_solver_window(int num)
{
int i, nbbutts = 0, newrow = 0;
static Fl_Group *g[10];
int LL = (int)(1.75 * IW);
int BBS = (5 * fontsize + 1); // smaller width of a button with internal label
if(solver[num].window) {
solver[num].window->show();
return;
}
for(i = 0; i < MAXSOLVERS; i++)
if(strlen(SINFO[num].option_name[i]))
SINFO[num].nboptions = i + 1;
for(i = 0; i < MAXSOLVERS; i++)
if(strlen(SINFO[num].button_name[i]))
nbbutts++;
if(nbbutts > 3)
newrow = 1;
int width = 5 * BBS + 6 * WB;
int height = (8 + SINFO[num].nboptions + newrow) * WB + (6 + SINFO[num].nboptions + newrow) * BH;
if(height < 8 * WB + 8 * BH)
height = 8 * WB + 8 * BH; //minimum height required by Options tab
solver[num].window = new Dialog_Window(width, height);
solver[num].window->box(GMSH_WINDOW_BOX);
{
Fl_Tabs *o = new Fl_Tabs(WB, WB, width - 2 * WB, height - (3 + newrow) * WB - (1 + newrow) * BH);
{
g[0] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - (3 + newrow) * WB - (2 + newrow) * BH, "General");
solver[num].input[0] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, LL, BH, "Problem");
Fl_Button *b1 = new Fl_Button(2 * WB, 3 * WB + 2 * BH, BB, BH, "Choose");
b1->callback(solver_file_open_cb, (void *)num);
Fl_Button *b2 = new Fl_Button(3 * WB + BB, 3 * WB + 2 * BH, BB, BH, "Edit");
b2->callback(solver_file_edit_cb, (void *)num);
solver[num].input[1] = new Fl_Input(2 * WB, 4 * WB + 3 * BH, LL, BH, "Mesh");
Fl_Button *b3 = new Fl_Button(2 * WB, 5 * WB + 4 * BH, BB, BH, "Choose");
b3->callback(solver_choose_mesh_cb, (void *)num);
for(i = 0; i < 2; i++) {
solver[num].input[i]->align(FL_ALIGN_RIGHT);
}
for(i = 0; i < SINFO[num].nboptions; i++) {
solver[num].choice[i] = new Fl_Choice(2 * WB, (6 + i) * WB + (5 + i) * BH, LL, BH, SINFO[num].option_name[i]);
solver[num].choice[i]->align(FL_ALIGN_RIGHT);
}
g[0]->end();
}
{
g[1] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - (3 + newrow) * WB - (2 + newrow) * BH, "Options");
solver[num].input[2] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, LL, BH, "Executable");
solver[num].input[2]->align(FL_ALIGN_RIGHT);
solver[num].input[2]->callback(solver_ok_cb);
Fl_Button *b = new Fl_Button(2 * WB, 3 * WB + 2 * BH, BB, BH, "Choose");
b->callback(solver_choose_executable_cb, (void *)num);
solver[num].butt[2] = new Fl_Check_Button(2 * WB, 4 * WB + 3 * BH, LL, BH, "Enable client-server connection");
solver[num].butt[2]->type(FL_TOGGLE_BUTTON);
solver[num].butt[2]->callback(solver_ok_cb);
solver[num].butt[0] = new Fl_Check_Button(2 * WB, 4 * WB + 4 * BH, LL, BH, "Display client messages");
solver[num].butt[0]->type(FL_TOGGLE_BUTTON);
solver[num].butt[0]->callback(solver_ok_cb);
solver[num].butt[1] = new Fl_Check_Button(2 * WB, 4 * WB + 5 * BH, LL, BH, "Merge views automatically");
solver[num].butt[1]->type(FL_TOGGLE_BUTTON);
solver[num].butt[1]->callback(solver_ok_cb);
{
Fl_Button *o = new Fl_Button(width - BB - 2 * WB,
height - (3 + newrow) * WB - (2 + newrow) * BH,
BB, BH, "Save");
o->callback(options_save_cb);
}
g[1]->end();
}
{
g[2] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - (3 + newrow) * WB - (2 + newrow) * BH, "About");
Fl_Browser *o = new Fl_Browser(2 * WB, 2 * WB + 1 * BH, width - 4 * WB,
height - (5 + newrow) * WB - (2 + newrow) * BH);
o->add(" ");
add_multiline_in_browser(o, "@c@b@.", SINFO[num].name);
o->add(" ");
add_multiline_in_browser(o, "@c@. ", SINFO[num].help);
g[2]->end();
}
o->end();
}
static int arg[MAXSOLVERS][5][2];
int nb = 0;
for(i = 4; i >= 0; i--) {
if(strlen(SINFO[num].button_name[i])) {
arg[num][i][0] = num;
arg[num][i][1] = i;
solver[num].command[nb] = new Fl_Button(width - (1 + nb + 2 * !newrow) * BBS - (1 + nb + 2 * !newrow) * WB,
height - (1 + newrow) * BH - (1 + newrow) * WB, BBS, BH,
SINFO[num].button_name[i]);
solver[num].command[nb]->callback(solver_command_cb, (void *)arg[num][i]);
nb++;
}
}
{
Fl_Button *o = new Fl_Button(width - 2 * BBS - 2 * WB, height - BH - WB, BBS, BH, "Kill");
o->callback(solver_kill_cb, (void *)num);
}
{
Fl_Button *o = new Fl_Button(width - BBS - WB, height - BH - WB, BBS, BH, "Cancel");
o->callback(cancel_cb, (void *)solver[num].window);
}
solver[num].window->position(CTX.solver_position[0], CTX.solver_position[1]);
solver[num].window->end();
}