diff --git a/Common/Context.h b/Common/Context.h index 2290a45fad8da9f7ec6db1a14a8cab8949880f6a..ed2f660b181f1966054c52cb575cf9ddb4715d4c 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -93,10 +93,8 @@ class CTX { std::string watchFilePattern; // show tootips in the GUI? int tooltips; - // scroll automatically to last message in the message window? - int msgAutoScroll; // position and size of various windows in the GUI - int menuPosition[2], glPosition[2], glSize[2], msgPosition[2], msgSize[2]; + int menuPosition[2], glPosition[2], glSize[2], msgSize; int optPosition[2], visPosition[2], clipPosition[2], manipPosition[2]; int statPosition[2], ctxPosition[2], solverPosition[2]; int pluginPosition[2], pluginSize[2], fieldPosition[2], fieldSize[2]; diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index 6181ff13887cb9a0b94b9ffec4aaf8884e1d4bc8..f7d827326d62028a508fc8bb3253f735ae0e5a11 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -724,18 +724,8 @@ StringXNumber GeneralOptions_Number[] = { "Horizontal position (in pixels) of the upper left corner of the menu window" }, { F|S, "MenuPositionY" , opt_general_menu_position1 , 50. , "Vertical position (in pixels) of the upper left corner of the menu window" }, - { F|O, "MessageAutoScroll" , opt_general_message_auto_scroll , 1. , - "Automatically scroll message window" }, - { F|S, "MessagePositionX" , opt_general_message_position0 , 650. , - "Horizontal position (in pixels) of the upper left corner of the message " - "window" }, - { F|S, "MessagePositionY" , opt_general_message_position1 , 490. , - "Vertical position (in pixels) of the upper left corner of the message " - "window" }, - { F|S, "MessageHeight" , opt_general_message_size1 , 300. , - "Height (in pixels) of the message window" }, - { F|S, "MessageWidth" , opt_general_message_size0 , 400. , - "Width (in pixels) of the message window" }, + { F|S, "MessageHeight" , opt_general_message_size , 300. , + "Height (in pixels) of the message console" }, { F, "MinX" , opt_general_xmin , 0. , "Minimum model coordinate along the X-axis (read-only)" }, { F, "MinY" , opt_general_ymin , 0. , diff --git a/Common/GmshMessage.cpp b/Common/GmshMessage.cpp index f5f303a7063839ef61ce70df9898b3ce0b847890..50feee990c26d4492db8998948fd9c44475ef30c 100644 --- a/Common/GmshMessage.cpp +++ b/Common/GmshMessage.cpp @@ -30,7 +30,6 @@ #if defined(HAVE_FLTK) #include <FL/fl_ask.H> #include "FlGui.h" -#include "messageWindow.h" #include "extraDialogs.h" #endif @@ -160,9 +159,9 @@ void Msg::Fatal(const char *fmt, ...) if(FlGui::available()){ FlGui::instance()->check(); std::string tmp = std::string("@C1@.") + "Fatal : " + str; - FlGui::instance()->messages->add(tmp.c_str()); - FlGui::instance()->messages->show(); - FlGui::instance()->messages->save + FlGui::instance()->addMessage(tmp.c_str()); + FlGui::instance()->showMessages(); + FlGui::instance()->saveMessages ((CTX::instance()->homeDir + CTX::instance()->errorFileName).c_str()); 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", @@ -201,8 +200,8 @@ void Msg::Error(const char *fmt, ...) if(FlGui::available()){ FlGui::instance()->check(); std::string tmp = std::string("@C1@.") + "Error : " + str; - FlGui::instance()->messages->add(tmp.c_str()); - FlGui::instance()->messages->show(); + FlGui::instance()->addMessage(tmp.c_str()); + FlGui::instance()->showMessages(); } #endif @@ -234,7 +233,7 @@ void Msg::Warning(const char *fmt, ...) if(FlGui::available()){ FlGui::instance()->check(); std::string tmp = std::string("@C1@.") + "Warning : " + str; - FlGui::instance()->messages->add(tmp.c_str()); + FlGui::instance()->addMessage(tmp.c_str()); } #endif @@ -261,7 +260,7 @@ void Msg::Info(const char *fmt, ...) if(FlGui::available()){ FlGui::instance()->check(); std::string tmp = std::string("Info : ") + str; - FlGui::instance()->messages->add(tmp.c_str()); + FlGui::instance()->addMessage(tmp.c_str()); } #endif @@ -305,9 +304,9 @@ void Msg::Direct(int level, const char *fmt, ...) tmp = std::string("@C1@.") + str; else tmp = std::string("@C4@.") + str; - FlGui::instance()->messages->add(tmp.c_str()); + FlGui::instance()->addMessage(tmp.c_str()); if(level == 1) - FlGui::instance()->messages->show(); + FlGui::instance()->showMessages(); } #endif @@ -338,7 +337,7 @@ void Msg::StatusBar(int num, bool log, const char *fmt, ...) FlGui::instance()->setStatus(str, num - 1); if(log){ std::string tmp = std::string("Info : ") + str; - FlGui::instance()->messages->add(tmp.c_str()); + FlGui::instance()->addMessage(tmp.c_str()); } } #endif @@ -365,7 +364,7 @@ void Msg::Debug(const char *fmt, ...) #if defined(HAVE_FLTK) if(FlGui::available()){ std::string tmp = std::string("Debug : ") + str; - FlGui::instance()->messages->add(tmp.c_str()); + FlGui::instance()->addMessage(tmp.c_str()); } #endif @@ -468,14 +467,14 @@ void Msg::PrintErrorCounter(const char *title) #if defined(HAVE_FLTK) if(FlGui::available()){ std::string red("@C1@."); - FlGui::instance()->messages->add((red + prefix + line).c_str()); - FlGui::instance()->messages->add((red + prefix + title).c_str()); - FlGui::instance()->messages->add((red + prefix + warn).c_str()); - FlGui::instance()->messages->add((red + prefix + err).c_str()); - FlGui::instance()->messages->add((red + prefix + help).c_str()); - FlGui::instance()->messages->add((red + prefix + line).c_str()); + FlGui::instance()->addMessage((red + prefix + line).c_str()); + FlGui::instance()->addMessage((red + prefix + title).c_str()); + FlGui::instance()->addMessage((red + prefix + warn).c_str()); + FlGui::instance()->addMessage((red + prefix + err).c_str()); + FlGui::instance()->addMessage((red + prefix + help).c_str()); + FlGui::instance()->addMessage((red + prefix + line).c_str()); if(_errorCount){ - FlGui::instance()->messages->show(); + FlGui::instance()->showMessages(); fl_beep(); } } diff --git a/Common/Options.cpp b/Common/Options.cpp index a19976e71c9319d06b73485d415f6714d369dd78..f3f2ade0dbaf667cb9944cef1297b9d166d2fc06 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -46,7 +46,6 @@ #include "optionWindow.h" #include "solverWindow.h" #include "manipWindow.h" -#include "messageWindow.h" #include "contextWindow.h" #include "clippingWindow.h" #endif @@ -2470,8 +2469,10 @@ double opt_general_graphics_position1(OPT_ARGS_NUM) double opt_general_graphics_size0(OPT_ARGS_NUM) { - if(action & GMSH_SET) + if(action & GMSH_SET){ CTX::instance()->glSize[0] = (int)val; + if(CTX::instance()->glSize[0] <= 0) CTX::instance()->glSize[0] = 800; + } #if defined(HAVE_FLTK) if(FlGui::available()){ if(action & GMSH_SET){ @@ -2489,8 +2490,10 @@ double opt_general_graphics_size0(OPT_ARGS_NUM) double opt_general_graphics_size1(OPT_ARGS_NUM) { - if(action & GMSH_SET) + if(action & GMSH_SET){ CTX::instance()->glSize[1] = (int)val; + if(CTX::instance()->glSize[1] <= 0) CTX::instance()->glSize[1] = 600; + } #if defined(HAVE_FLTK) if(FlGui::available()){ if(action & GMSH_SET){ @@ -2569,43 +2572,13 @@ double opt_general_system_menu_bar(OPT_ARGS_NUM) return CTX::instance()->systemMenuBar; } -double opt_general_message_position0(OPT_ARGS_NUM) -{ - if(action & GMSH_SET) - CTX::instance()->msgPosition[0] = (int)val; - return CTX::instance()->msgPosition[0]; -} - -double opt_general_message_position1(OPT_ARGS_NUM) -{ - if(action & GMSH_SET) - CTX::instance()->msgPosition[1] = (int)val; - return CTX::instance()->msgPosition[1]; -} - -double opt_general_message_size0(OPT_ARGS_NUM) +double opt_general_message_size(OPT_ARGS_NUM) { - if(action & GMSH_SET) - CTX::instance()->msgSize[0] = (int)val; - return CTX::instance()->msgSize[0]; -} - -double opt_general_message_size1(OPT_ARGS_NUM) -{ - if(action & GMSH_SET) - CTX::instance()->msgSize[1] = (int)val; - return CTX::instance()->msgSize[1]; -} - -double opt_general_message_auto_scroll(OPT_ARGS_NUM) -{ - if(action & GMSH_SET) - CTX::instance()->msgAutoScroll = (int)val; -#if defined(HAVE_FLTK) - if(FlGui::available() && (action & GMSH_GUI)) - FlGui::instance()->messages->butt->value(CTX::instance()->msgAutoScroll); -#endif - return CTX::instance()->msgAutoScroll; + if(action & GMSH_SET){ + CTX::instance()->msgSize = (int)val; + if(CTX::instance()->msgSize < 0) CTX::instance()->msgSize = 0; + } + return CTX::instance()->msgSize; } double opt_general_option_position0(OPT_ARGS_NUM) diff --git a/Common/Options.h b/Common/Options.h index d29b4addd026a155ddeab2bbd3e60181f68e2157..e80389fc05941916221ab22b6c6c259ddfff014b 100644 --- a/Common/Options.h +++ b/Common/Options.h @@ -252,11 +252,7 @@ double opt_general_polygon_offset_units(OPT_ARGS_NUM); double opt_general_menu_position0(OPT_ARGS_NUM); double opt_general_menu_position1(OPT_ARGS_NUM); double opt_general_system_menu_bar(OPT_ARGS_NUM); -double opt_general_message_position0(OPT_ARGS_NUM); -double opt_general_message_position1(OPT_ARGS_NUM); -double opt_general_message_size0(OPT_ARGS_NUM); -double opt_general_message_size1(OPT_ARGS_NUM); -double opt_general_message_auto_scroll(OPT_ARGS_NUM); +double opt_general_message_size(OPT_ARGS_NUM); double opt_general_option_position0(OPT_ARGS_NUM); double opt_general_option_position1(OPT_ARGS_NUM); double opt_general_plugin_position0(OPT_ARGS_NUM); diff --git a/Fltk/CMakeLists.txt b/Fltk/CMakeLists.txt index 3b6cbe786844d8037853e99603c2f3418f945e18..cbf7407a8fcd40cb22514ccd865970b5f5143c40 100644 --- a/Fltk/CMakeLists.txt +++ b/Fltk/CMakeLists.txt @@ -15,7 +15,6 @@ set(SRC statisticsWindow.cpp visibilityWindow.cpp clippingWindow.cpp - messageWindow.cpp manipWindow.cpp contextWindow.cpp solverWindow.cpp diff --git a/Fltk/FlGui.cpp b/Fltk/FlGui.cpp index 23892ba73935d19e2bef5d7533f4fa92ba28809f..e7f6737a487992097994229a69b03768e70cba3b 100644 --- a/Fltk/FlGui.cpp +++ b/Fltk/FlGui.cpp @@ -21,7 +21,6 @@ #include "statisticsWindow.h" #include "visibilityWindow.h" #include "clippingWindow.h" -#include "messageWindow.h" #include "manipWindow.h" #include "contextWindow.h" #include "solverWindow.h" @@ -268,7 +267,6 @@ FlGui::FlGui(int argc, char **argv) stats = new statisticsWindow(CTX::instance()->deltaFontSize); visibility = new visibilityWindow(CTX::instance()->deltaFontSize); clipping = new clippingWindow(CTX::instance()->deltaFontSize); - messages = new messageWindow(CTX::instance()->deltaFontSize); manip = new manipWindow(CTX::instance()->deltaFontSize); geoContext = new geometryContextWindow(CTX::instance()->deltaFontSize); meshContext = new meshContextWindow(CTX::instance()->deltaFontSize); @@ -785,11 +783,9 @@ void FlGui::storeCurrentWindowsInfo() CTX::instance()->glPosition[0] = graph[0]->win->x(); CTX::instance()->glPosition[1] = graph[0]->win->y(); CTX::instance()->glSize[0] = graph[0]->win->w(); - CTX::instance()->glSize[1] = (graph[0]->win->h() - graph[0]->bottom->h()); - CTX::instance()->msgPosition[0] = messages->win->x(); - CTX::instance()->msgPosition[1] = messages->win->y(); - CTX::instance()->msgSize[0] = messages->win->w(); - CTX::instance()->msgSize[1] = messages->win->h(); + CTX::instance()->glSize[1] = (graph[0]->win->h() - graph[0]->bottom->h() - + graph[0]->browser->h()); + CTX::instance()->msgSize = graph[0]->browser->h(); CTX::instance()->optPosition[0] = options->win->x(); CTX::instance()->optPosition[1] = options->win->y(); CTX::instance()->pluginPosition[0] = plugins->win->x(); @@ -852,8 +848,6 @@ void window_cb(Fl_Widget *w, void *data) FlGui::instance()->manip->win->iconize(); if(FlGui::instance()->stats->win->shown()) FlGui::instance()->stats->win->iconize(); - if(FlGui::instance()->messages->win->shown()) - FlGui::instance()->messages->win->iconize(); if(FlGui::instance()->menu->win->shown()) FlGui::instance()->menu->win->iconize(); } @@ -901,9 +895,23 @@ void window_cb(Fl_Widget *w, void *data) FlGui::instance()->manip->win->show(); if(FlGui::instance()->stats->win->shown()) FlGui::instance()->stats->win->show(); - if(FlGui::instance()->messages->win->shown()) - FlGui::instance()->messages->win->show(); FlGui::instance()->menu->win->show(); } } +void FlGui::addMessage(const char *msg) +{ + for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++) + FlGui::instance()->graph[i]->addMessage(msg); +} + +void FlGui::showMessages() +{ + for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++) + FlGui::instance()->graph[i]->showMessages(); +} + +void FlGui::saveMessages(const char *fileName) +{ + FlGui::instance()->graph[0]->saveMessages(fileName); +} diff --git a/Fltk/FlGui.h b/Fltk/FlGui.h index bc3b6563544a50be7bf2ae7bb8f08dd0775bad00..8a6f5a22ae008477bd12f014ae9d7f484afe5a10 100644 --- a/Fltk/FlGui.h +++ b/Fltk/FlGui.h @@ -28,7 +28,6 @@ class pluginWindow; class statisticsWindow; class visibilityWindow; class clippingWindow; -class messageWindow; class manipWindow; class geometryContextWindow; class meshContextWindow; @@ -59,7 +58,6 @@ class FlGui{ statisticsWindow *stats; visibilityWindow *visibility; clippingWindow *clipping; - messageWindow *messages; manipWindow *manip; geometryContextWindow *geoContext; meshContextWindow *meshContext; @@ -106,6 +104,12 @@ class FlGui{ void setStatus(const char *msg, int num); // create the window for physical context dependant definitions void callForSolverPlugin(int dim); + // add line in message console(s) + void addMessage(const char *msg); + // show the message console + void showMessages(); + // add line in message console(s) + void saveMessages(const char *fileName); }; void redraw_cb(Fl_Widget *w, void *data); diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp index 5406800492121c05522aea2888beb0a139e8efc6..b0696523ae08b87fa95561798317f1dd4c5b9f34 100644 --- a/Fltk/graphicWindow.cpp +++ b/Fltk/graphicWindow.cpp @@ -11,9 +11,9 @@ #include "paletteWindow.h" #include "mainWindow.h" #include "menuWindow.h" -#include "messageWindow.h" #include "manipWindow.h" #include "extraDialogs.h" +#include "fileDialogs.h" #include "PView.h" #include "PViewData.h" #include "OS.h" @@ -231,7 +231,7 @@ void status_options_cb(Fl_Widget *w, void *data) } else if(!strcmp(str, "?")){ // display options PrintOptions(0, GMSH_FULLRC, 0, 1, NULL); - FlGui::instance()->messages->show(); + FlGui::instance()->showMessages(); } else if(!strcmp(str, "p")){ // toggle projection mode if(!Fl::event_state(FL_SHIFT)){ @@ -417,6 +417,32 @@ static void remove_graphic_window_cb(Fl_Widget *w, void *data) } } +void message_cb(Fl_Widget *w, void *data) +{ + if(FlGui::instance()->graph[0]->browser->h()) + FlGui::instance()->graph[0]->hideMessages(); + else + FlGui::instance()->graph[0]->showMessages(); + FlGui::check(); +} + +static void message_event_cb(Fl_Widget *w, void *data) +{ + graphicWindow *g = (graphicWindow*)data; + + if(Fl::event_button() == 3 || Fl::event_state(FL_CTRL)){ + int a = Msg::GetAnswer("Save or clear messages?", 0, + "Cancel", "Save", "Clear"); + if(a == 1){ + if(fileChooser(FILE_CHOOSER_CREATE, "Save", "")) + g->saveMessages(fileChooserGetName(1).c_str()); + } + else if(a == 2) g->clearMessages(); + } + else + g->copySelectedMessagesToClipboard(); +} + // This dummy box class permits to define a box widget that will not // eat the FL_ENTER/FL_LEAVE events (the new Box widget in fltk > 1.1 // does that, so that gl->handle() was not called when the mouse @@ -447,8 +473,15 @@ graphicWindow::graphicWindow(bool main, int numTiles) int sh = 2 * FL_NORMAL_SIZE - 4; // status bar height int sw = FL_NORMAL_SIZE + 3; // status button width int width = CTX::instance()->glSize[0]; + int mheight = CTX::instance()->msgSize; int glheight = CTX::instance()->glSize[1]; - int height = glheight + sh; + int height = glheight + mheight + sh; + + // no tile should be zero during tile creation + if(CTX::instance()->msgSize <= 0 || CTX::instance()->msgSize >= glheight){ + mheight = 10; + glheight = CTX::instance()->glSize[1] - 10; + } // the graphic window should be a "normal" window (neither modal nor // non-modal) @@ -462,69 +495,69 @@ graphicWindow::graphicWindow(bool main, int numTiles) } // bottom button bar - bottom = new Fl_Box(0, glheight, width, sh); + bottom = new Fl_Box(0, glheight + mheight, width, sh); bottom->box(FL_FLAT_BOX); int x = 2; int sht = sh - 4; // leave a 2 pixel border at the bottom - butt[5] = new Fl_Button(x, glheight + 2, sw, sht, "@-1gmsh_models"); + butt[5] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_models"); butt[5]->callback(status_options_cb, (void *)"model"); butt[5]->tooltip("Select active model"); x += sw; - butt[0] = new Fl_Button(x, glheight + 2, sw, sht, "X"); + butt[0] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "X"); butt[0]->callback(status_xyz1p_cb, (void *)"x"); butt[0]->tooltip("Set +X or -X view (Alt+x or Alt+Shift+x)"); x += sw; - butt[1] = new Fl_Button(x, glheight + 2, sw, sht, "Y"); + butt[1] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "Y"); butt[1]->callback(status_xyz1p_cb, (void *)"y"); butt[1]->tooltip("Set +Y or -Y view (Alt+y or Alt+Shift+y)"); x += sw; - butt[2] = new Fl_Button(x, glheight + 2, sw, sht, "Z"); + butt[2] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "Z"); butt[2]->callback(status_xyz1p_cb, (void *)"z"); butt[2]->tooltip("Set +Z or -Z view (Alt+z or Alt+Shift+z)"); x += sw; - butt[4] = new Fl_Button(x, glheight + 2, sw, sht, "@-1gmsh_rotate"); + butt[4] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_rotate"); butt[4]->callback(status_xyz1p_cb, (void *)"r"); butt[4]->tooltip("Rotate +90 or -90 (Shift) degrees, or sync rotations (Alt)"); x += sw; - butt[3] = new Fl_Button(x, glheight + 2, 2 * FL_NORMAL_SIZE, sht, "1:1"); + butt[3] = new Fl_Button(x, glheight + mheight + 2, 2 * FL_NORMAL_SIZE, sht, "1:1"); butt[3]->callback(status_xyz1p_cb, (void *)"1:1"); butt[3]->tooltip("Set unit scale, sync scale between viewports (Alt), " "or reset bounding box around visible entities (Shift)"); x += 2 * FL_NORMAL_SIZE; - butt[8] = new Fl_Button(x, glheight + 2, sw, sht, "@-1gmsh_ortho"); + butt[8] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_ortho"); butt[8]->callback(status_options_cb, (void *)"p"); butt[8]->tooltip("Toggle projection mode (Alt+o or Alt+Shift+o)"); x += sw; - butt[12] = new Fl_Button(x, glheight + 2, sw, sht, "M"); + butt[12] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "M"); butt[12]->callback(status_options_cb, (void *)"M"); butt[12]->tooltip("Toggle mesh visibility (Alt+m)"); x += sw; - butt[13] = new Fl_Button(x, glheight + 2, sw, sht, "@-1gmsh_clscale"); + butt[13] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_clscale"); butt[13]->callback(status_options_cb, (void *)"clscale"); butt[13]->tooltip("Change mesh element size factor"); x += sw; - butt[9] = new Fl_Button(x, glheight + 2, sw, sht, "S"); + butt[9] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "S"); butt[9]->callback(status_options_cb, (void *)"S"); butt[9]->tooltip("Toggle mouse selection ON/OFF (Escape)"); x += sw; - butt[6] = new Fl_Button(x, glheight + 2, sw, sht, "@-1gmsh_rewind"); + butt[6] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_rewind"); butt[6]->callback(status_rewind_cb); butt[6]->tooltip("Rewind animation"); butt[6]->deactivate(); x += sw; - butt[10] = new Fl_Button(x, glheight + 2, sw, sht, "@-1gmsh_back"); + butt[10] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_back"); butt[10]->callback(status_stepbackward_cb); butt[10]->tooltip("Step backward"); butt[10]->deactivate(); x += sw; - butt[7] = new Fl_Button(x, glheight + 2, sw, sht, "@-1gmsh_play"); + butt[7] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_play"); butt[7]->callback(status_play_cb); butt[7]->tooltip("Play/pause animation"); butt[7]->deactivate(); x += sw; - butt[11] = new Fl_Button(x, glheight + 2, sw, sht, "@-1gmsh_forward"); + butt[11] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_forward"); butt[11]->callback(status_stepforward_cb); butt[11]->tooltip("Step forward"); butt[11]->deactivate(); @@ -540,8 +573,8 @@ graphicWindow::graphicWindow(bool main, int numTiles) int wleft = (width - x) / 3 - 1; int wright = (width - x) - (width - x) / 3 - 1; - label[0] = new Fl_Box(x, glheight + 2, wleft, sht); - label[1] = new Fl_Box(x + (width - x) / 3, glheight + 2, wright, sht); + label[0] = new Fl_Box(x, glheight + mheight + 2, wleft, sht); + label[1] = new Fl_Box(x + (width - x) / 3, glheight + mheight + 2, wright, sht); for(int i = 0; i < 2; i++) { label[i]->box(FL_THIN_DOWN_BOX); label[i]->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); @@ -557,7 +590,7 @@ graphicWindow::graphicWindow(bool main, int numTiles) win->size_range(minWidth, minHeight); // tiled opengl windows - tile = new Fl_Tile(0, 0, width, glheight); + tile = new Fl_Tile(0, 0, width, glheight + mheight); int w2 = width / 2, h2 = glheight / 2; if(numTiles == 2){ @@ -597,8 +630,20 @@ graphicWindow::graphicWindow(bool main, int numTiles) } for(unsigned int i = 0; i < gl.size(); i++) gl[i]->mode(mode); + browser = new Fl_Browser(0, glheight, width, mheight); + browser->box(FL_THIN_DOWN_BOX); + browser->textfont(FL_COURIER); + browser->textsize(FL_NORMAL_SIZE - 1); + browser->type(FL_MULTI_BROWSER); + browser->callback(message_event_cb, this); + browser->has_scrollbar(Fl_Browser_::VERTICAL); + tile->end(); + // resize the tile to match the prescribed sizes + tile->position(0, glheight, 0, CTX::instance()->glSize[1]); + _savedMessageHeight = CTX::instance()->msgSize; + win->position(CTX::instance()->glPosition[0], CTX::instance()->glPosition[1]); win->end(); } @@ -626,9 +671,12 @@ void graphicWindow::split(openglWindow *g, char how) // let's be brutal :-) int mode = g->mode(); openglWindow::setLastHandled(0); - tile->clear(); // this really deletes the child opengl windows + for(unsigned int i = 0; i < gl.size(); i++){ + tile->remove(gl[i]); + delete gl[i]; + } gl.clear(); - openglWindow *g2 = new openglWindow(0, 0, tile->w(), tile->h()); + openglWindow *g2 = new openglWindow(0, 0, tile->w(), tile->h() - browser->h()); g2->end(); g2->mode(mode); gl.push_back(g2); @@ -636,6 +684,8 @@ void graphicWindow::split(openglWindow *g, char how) g2->show(); } else{ + // make sure browser is not zero-size when adding children + if(browser->h() == 0) resizeMessages(1); int x1 = g->x(); int y1 = g->y(); int w1 = (how == 'h') ? g->w() / 2 : g->w(); @@ -698,3 +748,81 @@ void graphicWindow::checkAnimButtons() butt[11]->deactivate(); } } + +void graphicWindow::resizeMessages(int dh) +{ + for(unsigned int i = 0; i < gl.size(); i++){ + if(gl[i]->y() + gl[i]->h() == browser->y()) + gl[i]->resize(gl[i]->x(), gl[i]->y(), gl[i]->w(), gl[i]->h() - dh); + } + browser->resize(browser->x(), browser->y() - dh, browser->w(), browser->h() + dh); + browser->redraw(); +} + +void graphicWindow::showMessages() +{ + int height = _savedMessageHeight; + if(height < 10) height = 100; + int maxh = win->h() - bottom->h(); + if(height > maxh) height = maxh / 2; + resizeMessages(height - browser->h()); + if(browser->h()) + browser->bottomline(browser->size()); +} + +void graphicWindow::hideMessages() +{ + _savedMessageHeight = browser->h(); + resizeMessages(-browser->h()); +} + +void graphicWindow::addMessage(const char *msg) +{ + browser->add(msg, 0); + if(win->shown() && browser->h() >= 10) + browser->bottomline(browser->size()); +} + +void graphicWindow::clearMessages() +{ + browser->clear(); +} + +void graphicWindow::saveMessages(const char *filename) +{ + FILE *fp = fopen(filename, "w"); + + if(!fp) { + Msg::Error("Unable to open file '%s'", filename); + return; + } + + Msg::StatusBar(2, true, "Writing '%s'...", filename); + for(int i = 1; i <= browser->size(); i++) { + const char *c = browser->text(i); + if(c[0] == '@') + fprintf(fp, "%s\n", &c[5]); + else + fprintf(fp, "%s\n", c); + } + Msg::StatusBar(2, true, "Done writing '%s'", filename); + fclose(fp); +} + +void graphicWindow::copySelectedMessagesToClipboard() +{ + std::string buff; + for(int i = 1; i <= browser->size(); i++) { + if(browser->selected(i)) { + const char *c = browser->text(i); + if(strlen(c) > 5 && c[0] == '@') + buff += std::string(&c[5]); + else + buff += std::string(c); + buff += "\n"; + } + } + // bof bof bof + Fl::copy(buff.c_str(), buff.size(), 0); + Fl::copy(buff.c_str(), buff.size(), 1); +} diff --git a/Fltk/graphicWindow.h b/Fltk/graphicWindow.h index 74ba102ec2a2f6990d441eb5348fd34b0deb8e0d..865043487b74054d8ad9a63167fd5fbb572f9f0b 100644 --- a/Fltk/graphicWindow.h +++ b/Fltk/graphicWindow.h @@ -19,6 +19,7 @@ class graphicWindow{ private: std::string _title; + int _savedMessageHeight; public: Fl_Window *win; Fl_Tile *tile; @@ -35,13 +36,18 @@ class graphicWindow{ void split(openglWindow *g, char how); void setAnimButtons(int mode); void checkAnimButtons(); - void showMessages(int numLines); + void showMessages(); + void hideMessages(); + void resizeMessages(int dh); void addMessage(const char *msg); + void clearMessages(); void saveMessages(const char *filename); + void copySelectedMessagesToClipboard(); }; void status_xyz1p_cb(Fl_Widget *w, void *data); void status_options_cb(Fl_Widget *w, void *data); void status_play_manual(int time, int incr); +void message_cb(Fl_Widget *w, void *data); #endif diff --git a/Fltk/menuWindow.cpp b/Fltk/menuWindow.cpp index 8678b78674541600397edf701c132be8e46e9fbd..63080c901df0a34c069569025623cf7d52a33a9c 100644 --- a/Fltk/menuWindow.cpp +++ b/Fltk/menuWindow.cpp @@ -21,7 +21,6 @@ #include "graphicWindow.h" #include "optionWindow.h" #include "statisticsWindow.h" -#include "messageWindow.h" #include "contextWindow.h" #include "visibilityWindow.h" #include "clippingWindow.h" @@ -587,7 +586,7 @@ static void help_short_cb(Fl_Widget *w, void *data) Msg::Direct(" Alt+Shift+y Set -Y view"); Msg::Direct(" Alt+Shift+z Set -Z view"); Msg::Direct(" "); - FlGui::instance()->messages->show(); + FlGui::instance()->showMessages(); } #undef CC @@ -617,14 +616,14 @@ static void help_mouse_cb(Fl_Widget *w, void *data) Msg::Direct(" For a 1 button mouse, Middle button = Shift+Left button, " "Right button = Alt+Left button"); Msg::Direct(" "); - FlGui::instance()->messages->show(); + FlGui::instance()->showMessages(); } static void help_command_line_cb(Fl_Widget *w, void *data) { Msg::Direct(" "); PrintUsage("gmsh"); - FlGui::instance()->messages->show(); + FlGui::instance()->showMessages(); } static void help_online_cb(Fl_Widget *w, void *data) @@ -1800,7 +1799,7 @@ static void mesh_inspect_cb(Fl_Widget *w, void *data) Msg::Direct(" Disto: %g", ele->distoShapeMeasure()); CTX::instance()->mesh.changed = ENT_ALL; drawContext::global()->draw(); - FlGui::instance()->messages->show(); + FlGui::instance()->showMessages(); } } if(ib == 'q') { diff --git a/Fltk/messageWindow.cpp b/Fltk/messageWindow.cpp deleted file mode 100644 index baab79180f16d9f5aed02a5a563fd6709caf6175..0000000000000000000000000000000000000000 --- a/Fltk/messageWindow.cpp +++ /dev/null @@ -1,148 +0,0 @@ -// Gmsh - Copyright (C) 1997-2011 C. Geuzaine, J.-F. Remacle -// -// See the LICENSE.txt file for license information. Please report all -// bugs and problems to <gmsh@geuz.org>. - -#include <stdio.h> -#include <string.h> -#include <FL/Fl_Box.H> -#include <FL/Fl_Return_Button.H> -#include <FL/fl_ask.H> -#include "FlGui.h" -#include "messageWindow.h" -#include "paletteWindow.h" -#include "fileDialogs.h" -#include "GmshMessage.h" -#include "OS.h" -#include "Context.h" - -void message_cb(Fl_Widget *w, void *data) -{ - FlGui::instance()->messages->show(); -} - -static void message_auto_scroll_cb(Fl_Widget *w, void *data) -{ - CTX::instance()->msgAutoScroll = FlGui::instance()->messages->butt->value(); -} - -static void message_copy_cb(Fl_Widget *w, void *data) -{ - std::string buff; - for(int i = 1; i <= FlGui::instance()->messages->browser->size(); i++) { - if(FlGui::instance()->messages->browser->selected(i)) { - const char *c = FlGui::instance()->messages->browser->text(i); - if(strlen(c) > 5 && c[0] == '@') - buff += std::string(&c[5]); - else - buff += std::string(c); - buff += "\n"; - } - } - // bof bof bof - Fl::copy(buff.c_str(), buff.size(), 0); - Fl::copy(buff.c_str(), buff.size(), 1); -} - -static void message_clear_cb(Fl_Widget *w, void *data) -{ - FlGui::instance()->messages->browser->clear(); -} - -static void message_save_cb(Fl_Widget *w, void *data) -{ - test: - if(fileChooser(FILE_CHOOSER_CREATE, "Save", "*")) { - std::string name = fileChooserGetName(1); - if(CTX::instance()->confirmOverwrite) { - if(!StatFile(name)) - if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", - "Cancel", "Replace", NULL, name.c_str())) - goto test; - } - FlGui::instance()->messages->save(name.c_str()); - } -} - -messageWindow::messageWindow(int deltaFontSize) -{ - FL_NORMAL_SIZE -= deltaFontSize; - - int width = CTX::instance()->msgSize[0]; - int height = CTX::instance()->msgSize[1]; - - win = new paletteWindow - (width, height, CTX::instance()->nonModalWindows ? true : false, "Message Console"); - win->box(GMSH_WINDOW_BOX); - - browser = new Fl_Browser(0, 0, width, height - 2 * WB - BH); - browser->box(FL_FLAT_BOX); - browser->textfont(FL_COURIER); - browser->textsize(FL_NORMAL_SIZE - 1); - browser->type(FL_MULTI_BROWSER); - browser->callback(message_copy_cb); - - { - butt = new Fl_Check_Button - (width - 3 * BB - 3 * WB, height - BH - WB, BB, BH, "Auto scroll"); - butt->type(FL_TOGGLE_BUTTON); - butt->callback(message_auto_scroll_cb); - } - { - Fl_Return_Button *o = new Fl_Return_Button - (width - 2 * BB - 2 * WB, height - BH - WB, BB, BH, "Clear"); - o->callback(message_clear_cb); - } - { - Fl_Button *o = new Fl_Button - (width - BB - WB, height - BH - WB, BB, BH, "Save"); - o->callback(message_save_cb); - } - - win->resizable(new Fl_Box(1, 1, 4, 4)); - win->size_range(3 * BB + 4 * WB, 100); - - win->position(CTX::instance()->msgPosition[0], CTX::instance()->msgPosition[1]); - win->end(); - - FL_NORMAL_SIZE += deltaFontSize; -} - -void messageWindow::add(const char *msg) -{ - browser->add(msg, 0); - if(win->shown() && CTX::instance()->msgAutoScroll) - browser->bottomline(browser->size()); -} - -void messageWindow::save(const char *filename) -{ - FILE *fp = fopen(filename, "w"); - - if(!fp) { - Msg::Error("Unable to open file '%s'", filename); - return; - } - - Msg::StatusBar(2, true, "Writing '%s'...", filename); - for(int i = 1; i <= browser->size(); i++) { - const char *c = browser->text(i); - if(c[0] == '@') - fprintf(fp, "%s\n", &c[5]); - else - fprintf(fp, "%s\n", c); - } - Msg::StatusBar(2, true, "Done writing '%s'", filename); - fclose(fp); -} - -void messageWindow::show(bool redrawOnly) -{ - if(CTX::instance()->msgAutoScroll) - browser->bottomline(browser->size()); - - if(win->shown() && redrawOnly) - win->redraw(); - else - win->show(); -} diff --git a/Fltk/messageWindow.h b/Fltk/messageWindow.h deleted file mode 100644 index 1b20311efb77aa4cea4ea0dd0aa935d62b40ed11..0000000000000000000000000000000000000000 --- a/Fltk/messageWindow.h +++ /dev/null @@ -1,27 +0,0 @@ -// Gmsh - Copyright (C) 1997-2011 C. Geuzaine, J.-F. Remacle -// -// See the LICENSE.txt file for license information. Please report all -// bugs and problems to <gmsh@geuz.org>. - -#ifndef _MESSAGE_WINDOW_H_ -#define _MESSAGE_WINDOW_H_ - -#include <FL/Fl_Window.H> -#include <FL/Fl_Browser.H> -#include <FL/Fl_Check_Button.H> - -class messageWindow{ - public: - Fl_Window *win; - Fl_Browser *browser; - Fl_Check_Button *butt; - public: - messageWindow(int deltaFontSize); - void show(bool redrawOnly=false); - void add(const char *msg); - void save(const char *filename); -}; - -void message_cb(Fl_Widget *w, void *data); - -#endif diff --git a/Fltk/openglWindow.cpp b/Fltk/openglWindow.cpp index 6b0f0a7030b05dc997c71cebcb5306af84ab8e09..6814e4b242ea272a82276dd88b2dae5d8a3cb83b 100644 --- a/Fltk/openglWindow.cpp +++ b/Fltk/openglWindow.cpp @@ -83,8 +83,9 @@ void openglWindow::_drawScreenMessage() void openglWindow::_drawBorder() { - // draw thin border if the parent group has several children - if(parent()->children() > 1){ + // draw thin border if the parent group has more than 2 children (it + // has at least 2: the message console and one opengl window) + if(parent()->children() > 2){ unsigned char r, g, b; Fl::get_color(color(), r, g, b); /* would need to redraw all gl's when _lastHandled is changed diff --git a/Fltk/solverWindow.cpp b/Fltk/solverWindow.cpp index 2ef8edd82f36af50b3fe28b44237d69f2b5fed49..4d34215d18e6802fb558cb8e4923cff3973b7c56 100644 --- a/Fltk/solverWindow.cpp +++ b/Fltk/solverWindow.cpp @@ -20,7 +20,6 @@ #include "menuWindow.h" #include "solverWindow.h" #include "paletteWindow.h" -#include "messageWindow.h" #include "fileDialogs.h" #include "StringUtils.h" #include "Options.h" @@ -395,7 +394,7 @@ static void solver_command_cb(Fl_Widget *w, void *data) int idx = ((int *)data)[1]; if(ConnectionManager::get(num)->popupMessages) - FlGui::instance()->messages->show(true); + FlGui::instance()->showMessages(); int optionIndex = 0; for(int i = 0; i < idx; i++)