From ea7e789da99b519fbef68792f86472418db2fb38 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Thu, 6 Jun 2013 07:51:08 +0000
Subject: [PATCH] new option menu for solvers (much simpler than in gear menu);
 needs to be enhanced with other actions

---
 Fltk/CMakeLists.txt    |  2 +-
 Fltk/graphicWindow.cpp |  2 +-
 Fltk/onelabGroup.cpp   | 62 ++++++++++++------------------------------
 Fltk/onelabGroup.h     |  2 +-
 Fltk/solverButton.cpp  | 58 +++++++++++++++++++++++++++++++++++++++
 Fltk/solverButton.h    | 26 ++++++++++++++++++
 6 files changed, 105 insertions(+), 47 deletions(-)
 create mode 100644 Fltk/solverButton.cpp
 create mode 100644 Fltk/solverButton.h

diff --git a/Fltk/CMakeLists.txt b/Fltk/CMakeLists.txt
index 6468c1d790..101ed72a7b 100644
--- a/Fltk/CMakeLists.txt
+++ b/Fltk/CMakeLists.txt
@@ -28,7 +28,7 @@ set(SRC
     partitionDialog.cpp
     onelabGroup.cpp
     inputRegion.cpp
-    viewButton.cpp
+    viewButton.cpp solverButton.cpp
     Navigator.cpp
 )
 
diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp
index 1b3bf57fb3..a9bd8a2943 100644
--- a/Fltk/graphicWindow.cpp
+++ b/Fltk/graphicWindow.cpp
@@ -3328,7 +3328,7 @@ void onelabGroup::_addGmshMenus()
   // add dynamic solver module items
   for(int i = 0; i < 5; i++){
     std::string name = opt_solver_name(i, GMSH_GET, "");
-    if(name.size()) _addMenu("0Modules/Solver/" + name, solver_cb, (void*)i);
+    if(name.size()) _addSolverMenu(i);
   }
 
   // add dynamic post-processing module items
diff --git a/Fltk/onelabGroup.cpp b/Fltk/onelabGroup.cpp
index e44d168dcc..53e49d0601 100644
--- a/Fltk/onelabGroup.cpp
+++ b/Fltk/onelabGroup.cpp
@@ -25,6 +25,7 @@ typedef unsigned long intptr_t;
 #include "inputRange.h"
 #include "outputRange.h"
 #include "inputRegion.h"
+#include "solverButton.h"
 #include "viewButton.h"
 #include "paletteWindow.h"
 #include "graphicWindow.h"
@@ -889,16 +890,10 @@ static void onelab_choose_executable_cb(Fl_Widget *w, void *data)
   }
 }
 
-static void onelab_remove_solver_cb(Fl_Widget *w, void *data)
-{
-  onelab::client *c = (onelab::client*)data;
-  FlGui::instance()->onelab->removeSolver(c->getName());
-}
-
 static void onelab_add_solver_cb(Fl_Widget *w, void *data)
 {
   for(int i = 0; i < 5; i++){
-    if(opt_solver_name(i, GMSH_GET, "").empty()){
+    if(opt_solver_name(i, GMSH_GET, "").empty() || i == 4){
       const char *name = fl_input("Client name:", "");
       if(name){
         FlGui::instance()->onelab->addSolver(name, "", "", i);
@@ -1032,6 +1027,7 @@ onelabGroup::onelabGroup(int x, int y, int w, int h, const char *l)
   _gear->add("Reset database", 0, onelab_cb, (void*)"reset");
   _gear->add("Save database...", 0, onelab_cb, (void*)"save");
   _gear->add("_Load database...", 0, onelab_cb, (void*)"load");
+  _gear->add("_Add new solver...", 0, onelab_add_solver_cb);
 
   _minWindowWidth = 3 * BB2 + 4 * WB;
   _minWindowHeight = 2 * BH + 3 * WB;
@@ -1050,7 +1046,7 @@ onelabGroup::onelabGroup(int x, int y, int w, int h, const char *l)
              FL_MENU_TOGGLE);
   _gear->add("Hide new views", 0, onelab_option_cb, (void*)"hide",
              FL_MENU_TOGGLE);
-  _gear->add("_Always show last step", 0, onelab_option_cb, (void*)"step",
+  _gear->add("Always show last step", 0, onelab_option_cb, (void*)"step",
              FL_MENU_TOGGLE);
 
   _gearOptionsEnd = _gear->menu()->size();
@@ -1130,6 +1126,19 @@ void onelabGroup::_addMenu(const std::string &path, Fl_Callback *callback, void
   _tree->end();
 }
 
+void onelabGroup::_addSolverMenu(int num)
+{
+  std::ostringstream path;
+  path << "0Modules/Solver/Solver" << num;
+  Fl_Tree_Item *n = _tree->add(path.str().c_str());
+  int ww = _baseWidth - (n->depth() + 1) * _indent;
+  _tree->begin();
+  solverButton *but = new solverButton(1, 1, ww, 1, num, _tree->color());
+  _treeWidgets.push_back(but);
+  n->widget(but);
+  _tree->end();
+}
+
 void onelabGroup::_addViewMenu(int num)
 {
   std::ostringstream path;
@@ -1748,8 +1757,7 @@ bool onelabGroup::isBusy()
 
 void onelabGroup::rebuildSolverList()
 {
-  // update OneLab window title and gear menu
-  _title = "OneLab";
+  // update gear menu
   Fl_Menu_Item* menu = (Fl_Menu_Item*)_gear->menu();
   int values[7] = {CTX::instance()->solver.autoSaveDatabase,
                    CTX::instance()->solver.autoArchiveOutputFiles,
@@ -1765,23 +1773,6 @@ void onelabGroup::rebuildSolverList()
     else
       menu[idx].clear();
   }
-  for(int i = menu->size(); i >= _gearOptionsEnd - 1; i--)
-    _gear->remove(i);
-  for(onelab::server::citer it = onelab::server::instance()->firstClient();
-      it != onelab::server::instance()->lastClient(); it++){
-    if(it == onelab::server::instance()->firstClient()) _title += " -";
-    if(it->second->isNetworkClient()){
-      onelab::localNetworkClient *c = (onelab::localNetworkClient*)it->second;
-      char tmp[256];
-      sprintf(tmp, "%s/Choose executable", c->getName().c_str());
-      _gear->add(tmp, 0, onelab_choose_executable_cb, (void*)c);
-      sprintf(tmp, "%s/Remove", c->getName().c_str());
-      _gear->add(tmp, 0, onelab_remove_solver_cb, (void*)c);
-    }
-    _title += " " + it->second->getName();
-  }
-  _gear->add("Add new client...", 0, onelab_add_solver_cb);
-  //label(_title.c_str());
 
   // update Gmsh solver menu
   std::vector<std::string> names, exes, hosts;
@@ -1860,23 +1851,6 @@ void onelabGroup::addSolver(const std::string &name, const std::string &executab
   onelab_cb(0, (void*)"initialize");
 }
 
-void onelabGroup::removeSolver(const std::string &name)
-{
-  onelab::server::citer it = onelab::server::instance()->findClient(name);
-  if(it != onelab::server::instance()->lastClient()){
-    onelab::client *c = it->second;
-    if(c->isNetworkClient()){
-      if(c->getIndex() >= 0 && c->getIndex() < 5){
-        opt_solver_name(c->getIndex(), GMSH_SET, "");
-        opt_solver_executable(c->getIndex(), GMSH_SET, "");
-        opt_solver_remote_login(c->getIndex(), GMSH_SET, "");
-      }
-      delete c;
-    }
-  }
-  FlGui::instance()->onelab->rebuildSolverList();
-}
-
 void solver_cb(Fl_Widget *w, void *data)
 {
   int num = (intptr_t)data;
diff --git a/Fltk/onelabGroup.h b/Fltk/onelabGroup.h
index da87388062..69cb569288 100644
--- a/Fltk/onelabGroup.h
+++ b/Fltk/onelabGroup.h
@@ -24,7 +24,6 @@ class onelabGroup : public Fl_Group{
   int _gearOptionsStart, _gearOptionsEnd;
   std::vector<Fl_Widget*> _treeWidgets;
   std::vector<char*> _treeStrings;
-  std::string _title;
   bool _stop;
   int _baseWidth, _indent;
   int _minWindowWidth, _minWindowHeight;
@@ -40,6 +39,7 @@ class onelabGroup : public Fl_Group{
   Fl_Widget *_addParameterWidget(onelab::function &p, Fl_Tree_Item *n,
                                  bool highlight, Fl_Color c);
   void _addMenu(const std::string &path, Fl_Callback *callback, void *data);
+  void _addSolverMenu(int num);
   void _addViewMenu(int num);
   std::set<std::string> _getClosedGmshMenus();
   void _addGmshMenus();
diff --git a/Fltk/solverButton.cpp b/Fltk/solverButton.cpp
new file mode 100644
index 0000000000..77e15a06ad
--- /dev/null
+++ b/Fltk/solverButton.cpp
@@ -0,0 +1,58 @@
+// Gmsh - Copyright (C) 1997-2013 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to the public mailing list <gmsh@geuz.org>.
+
+#include "FlGui.h"
+#include "Options.h"
+#include "onelabGroup.h"
+#include "solverButton.h"
+
+static void solver_remove_cb(Fl_Widget *w, void *data)
+{
+  int num = (intptr_t)data;
+
+  std::string name = opt_solver_name(num, GMSH_GET, "");
+  opt_solver_name(num, GMSH_SET, "");
+  opt_solver_executable(num, GMSH_SET, "");
+  opt_solver_remote_login(num, GMSH_SET, "");
+
+  onelab::server::citer it = onelab::server::instance()->findClient(name);
+  if(it != onelab::server::instance()->lastClient()){
+    onelab::client *c = it->second;
+    delete c;
+  }
+  FlGui::instance()->onelab->rebuildSolverList();
+}
+
+solverButton::solverButton(int x, int y, int w, int h, int num, Fl_Color col)
+  : Fl_Group(x,y,w,h)
+{
+  int popw = FL_NORMAL_SIZE + 2;
+
+  _butt[0] = new Fl_Button(x, y, w - popw, h);
+  _butt[0]->box(FL_FLAT_BOX);
+  _butt[0]->color(col);
+  _butt[0]->selection_color(col);
+  _butt[0]->callback(solver_cb, (void *)num);
+  _butt[0]->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
+
+  std::string name = opt_solver_name(num, GMSH_GET, "");
+  _butt[0]->copy_label(name.c_str());
+  std::string exe = opt_solver_executable(num, GMSH_GET, "");
+  strcpy(_tooltip, exe.c_str());
+  _butt[0]->tooltip(_tooltip);
+
+  _butt[1] = new Fl_Button(x + w - popw, y, popw, h, "@>");
+  _butt[1]->align(FL_ALIGN_RIGHT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
+  _butt[1]->tooltip("Show solver option menu");
+  _butt[1]->box(FL_FLAT_BOX);
+  _butt[1]->color(col);
+  _butt[1]->selection_color(col);
+  _popup = new Fl_Menu_Button(x + w - popw, y, popw, h);
+  _popup->type(Fl_Menu_Button::POPUP123);
+  _popup->add("Remove", 0, (Fl_Callback *)solver_remove_cb, (void *)num, 0);
+
+  end(); // close the group
+  resizable(_butt[0]);
+}
diff --git a/Fltk/solverButton.h b/Fltk/solverButton.h
new file mode 100644
index 0000000000..292e82eb77
--- /dev/null
+++ b/Fltk/solverButton.h
@@ -0,0 +1,26 @@
+// Gmsh - Copyright (C) 1997-2013 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to the public mailing list <gmsh@geuz.org>.
+
+#ifndef _SOLVER_BUTTON_H_
+#define _SOLVER_BUTTON_H_
+
+#include <string>
+#include <FL/Fl.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Menu_Button.H>
+
+class solverButton : public Fl_Group {
+ private:
+  Fl_Button *_butt[2];
+  Fl_Menu_Button *_popup;
+  char _tooltip[256], _arrow[32];
+ public:
+  solverButton(int x, int y, int w, int h, int num, Fl_Color col);
+  void copy_label(const std::string &label){ _butt[0]->copy_label(label.c_str()); }
+  std::string label(){ return _butt[0]->label(); }
+};
+
+#endif
-- 
GitLab