From 83253b3895b3b92c4f3dbe8e98ea98ccb2dc0dc2 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Tue, 2 Dec 2008 16:45:04 +0000
Subject: [PATCH] small bits for multi-views

---
 Fltk/Draw.cpp          | 61 ++++++++++++++++++++++++------------------
 Fltk/Draw.h            |  8 +++---
 Fltk/GUI.cpp           | 29 +++++++++++++-------
 Fltk/graphicWindow.cpp | 23 +++++++++++-----
 Fltk/graphicWindow.h   |  2 +-
 Fltk/openglWindow.cpp  | 15 +++++------
 Fltk/openglWindow.h    |  3 ++-
 7 files changed, 85 insertions(+), 56 deletions(-)

diff --git a/Fltk/Draw.cpp b/Fltk/Draw.cpp
index 5faf16e664..579062a7fd 100644
--- a/Fltk/Draw.cpp
+++ b/Fltk/Draw.cpp
@@ -23,10 +23,14 @@
 
 extern Context_T CTX;
 
-void SetOpenglContext()
+void Draw()
 {
   if(!GUI::available()) return;
-  GUI::instance()->graph[0]->gl->make_current();
+  for(unsigned int i = 0; i < GUI::instance()->graph.size(); i++){
+    GUI::instance()->graph[i]->gl->make_current();
+    GUI::instance()->graph[i]->gl->redraw();
+  }
+  GUI::instance()->check();
 }
 
 void ClearOpengl()
@@ -37,19 +41,20 @@ void ClearOpengl()
   glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
 }
 
-void Draw()
+void SetOpenglContext(int index)
 {
   if(!GUI::available()) return;
-  GUI::instance()->graph[0]->gl->make_current();
-  GUI::instance()->graph[0]->gl->redraw();
-  GUI::instance()->check();
+  if(index >= 0 && index < GUI::instance()->graph.size())
+    GUI::instance()->graph[index]->gl->make_current();
 }
 
-void Draw2d3d()
+void Draw2d3d(int index)
 {
   if(!GUI::available()) return;
-  GUI::instance()->graph[0]->gl->getDrawContext()->draw3d();
-  GUI::instance()->graph[0]->gl->getDrawContext()->draw2d();
+  if(index >= 0 && index < GUI::instance()->graph.size()){
+    GUI::instance()->graph[index]->gl->getDrawContext()->draw3d();
+    GUI::instance()->graph[index]->gl->getDrawContext()->draw2d();
+  }
 }
 
 void DrawPlugin(void (*draw)(void *context))
@@ -168,35 +173,39 @@ void Draw_String(std::string s, double style)
   }
 }
 
-void Draw_OnScreenMessages()
+void Draw_OnScreenMessages(int index)
 {
   if(!GUI::available()) return;
 
   glColor4ubv((GLubyte *) & CTX.color.text);
   gl_font(CTX.gl_font_enum, CTX.gl_fontsize);
   double h = gl_height();
+
+  if(index >= 0 && index < GUI::instance()->graph.size()){
+    drawContext *ctx = GUI::instance()->graph[index]->gl->getDrawContext();
   
-  drawContext *ctx = GUI::instance()->graph[0]->gl->getDrawContext();
-  
-  if(strlen(GUI::instance()->onscreen_buffer[0])){
-    double w = gl_width(GUI::instance()->onscreen_buffer[0]);
-    glRasterPos2d(ctx->viewport[2] / 2. - w / 2., 
-                  ctx->viewport[3] - 1.2 * h);
-    gl_draw(GUI::instance()->onscreen_buffer[0]);
-  }
-  if(strlen(GUI::instance()->onscreen_buffer[1])){
-    double w = gl_width(GUI::instance()->onscreen_buffer[1]);
-    glRasterPos2d(ctx->viewport[2] / 2. - w / 2.,
-                  ctx->viewport[3] - 2.4 * h);
-    gl_draw(GUI::instance()->onscreen_buffer[1]);
+    if(strlen(GUI::instance()->onscreen_buffer[0])){
+      double w = gl_width(GUI::instance()->onscreen_buffer[0]);
+      glRasterPos2d(ctx->viewport[2] / 2. - w / 2., 
+                    ctx->viewport[3] - 1.2 * h);
+      gl_draw(GUI::instance()->onscreen_buffer[0]);
+    }
+    if(strlen(GUI::instance()->onscreen_buffer[1])){
+      double w = gl_width(GUI::instance()->onscreen_buffer[1]);
+      glRasterPos2d(ctx->viewport[2] / 2. - w / 2.,
+                    ctx->viewport[3] - 2.4 * h);
+      gl_draw(GUI::instance()->onscreen_buffer[1]);
+    }
   }
 }
 
-void GetStoredViewport(int viewport[4])
+void GetStoredViewport(int viewport[4], int index)
 {
   if(!GUI::available()) return;
-  for(int i = 0; i < 4; i++)
-    viewport[i] = GUI::instance()->graph[0]->gl->getDrawContext()->viewport[i];
+  if(index >= 0 && index < GUI::instance()->graph.size()){
+    for(int i = 0; i < 4; i++)
+      viewport[i] = GUI::instance()->graph[index]->gl->getDrawContext()->viewport[i];
+  }
 }
 
 void Viewport2World(double win[3], double xyz[3])
diff --git a/Fltk/Draw.h b/Fltk/Draw.h
index e23db3134a..d6d8463407 100644
--- a/Fltk/Draw.h
+++ b/Fltk/Draw.h
@@ -8,20 +8,20 @@
 
 #include <string>
 
-void SetOpenglContext();
+void SetOpenglContext(int index=0);
 void ClearOpengl();
 
 void Draw();
-void Draw2d3d();
+void Draw2d3d(int index=0);
 void DrawPlugin(void (*draw)(void *context));
 
 void Draw_String(std::string);
 void Draw_String(std::string, double style);
 void Draw_String_Center(std::string);
 void Draw_String_Right(std::string);
-void Draw_OnScreenMessages();
+void Draw_OnScreenMessages(int index=0);
 
-void GetStoredViewport(int viewport[4]);
+void GetStoredViewport(int viewport[4], int index=0);
 void Viewport2World(double win[3], double xyz[3]);
 void World2Viewport(double xyz[3], double win[3]);
 
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index c098616c6a..8a3980fa75 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -115,7 +115,7 @@ GUI::GUI(int argc, char **argv)
     0x20, 0x00, 0xff, 0x07, 0x10, 0x00, 0xff, 0x0f, 0x10, 0x00, 0xff, 0x0f,
     0x08, 0x00, 0xff, 0x1f, 0x08, 0x00, 0xff, 0x1f, 0x04, 0x40, 0xfd, 0x3f,
     0x04, 0xa8, 0xea, 0x3f, 0x02, 0x55, 0x55, 0x7f, 0xa2, 0xaa, 0xaa, 0x7a,
-    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
+    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00};
   graph[0]->win->icon
     ((const char*)XCreateBitmapFromData(fl_display, DefaultRootWindow(fl_display),
                                         gmsh32x32, 32, 32));
@@ -134,8 +134,10 @@ GUI::GUI(int argc, char **argv)
   graph[0]->gl->take_focus();
 
   // test: create another graphic window
-  //graph.push_back(new graphicWindow(_fontsize));
-  //graph[1]->win->show();
+  //double mat[3][3]={{3,0,0}, {0,1,0}, {0,0,1}};
+  //drawContext *ctx = new drawContext(new drawTransformScaled(mat));
+  //graph.push_back(new graphicWindow(_fontsize, ctx));
+  //graph.back()->win->show();
 
   options = new optionWindow(_fontsize);
   fields = new fieldWindow(_fontsize);
@@ -155,7 +157,8 @@ GUI::GUI(int argc, char **argv)
   callForSolverPlugin(-1);
 
   // draw the scene
-  graph[0]->gl->redraw();
+  for(unsigned int i = 0; i < graph.size(); i++)
+    graph[i]->gl->redraw();
 }
 
 GUI *GUI::_instance = 0;
@@ -518,12 +521,14 @@ void GUI::setGraphicTitle(const char *str)
 {
   // FIXME should use copy_label, but it is broken for Fl_Windows in
   // fltk 1.1.7
-  graph[0]->win->label(str);
+  for(unsigned int i = 0; i < graph.size(); i++)
+    graph[i]->win->label(str);
 }
 
 void GUI::updateViews()
 {
-  graph[0]->checkAnimButtons();
+  for(unsigned int i = 0; i < graph.size(); i++)
+    graph[i]->checkAnimButtons();
   if(menu->module->value() == 3)
     menu->setContext(menu_post, 0);
   options->resetBrowser();
@@ -551,8 +556,10 @@ void GUI::setStatus(const char *msg, int num)
     static char buff[2][1024];
     strncpy(buff[num], msg, sizeof(buff[num]) - 1);
     buff[num][sizeof(buff[num]) - 1] = '\0';
-    graph[0]->label[num]->label(buff[num]);
-    graph[0]->label[num]->redraw();
+    for(unsigned int i = 0; i < graph.size(); i++){
+      graph[i]->label[num]->label(buff[num]);
+      graph[i]->label[num]->redraw();
+    }
   }
   else if(num == 2){
     int n = strlen(msg);
@@ -628,7 +635,8 @@ void window_cb(Fl_Widget *w, void *data)
   const char *str = (const char*)data;
 
   if(!strcmp(str, "minimize")){
-    GUI::instance()->graph[0]->win->iconize();
+    for(unsigned int i = 0; i < GUI::instance()->graph.size(); i++)
+      GUI::instance()->graph[i]->win->iconize();
     GUI::instance()->options->win->iconize();
     GUI::instance()->plugins->win->iconize();
     GUI::instance()->fields->win->iconize();
@@ -657,7 +665,8 @@ void window_cb(Fl_Widget *w, void *data)
   }
   else if(!strcmp(str, "front")){
     // the order is important!
-    GUI::instance()->graph[0]->win->show();
+    for(unsigned int i = 0; i < GUI::instance()->graph.size(); i++)
+      GUI::instance()->graph[i]->win->show();
     if(GUI::instance()->options->win->shown()) 
       GUI::instance()->options->win->show();
     if(GUI::instance()->plugins->win->shown())
diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp
index 8eaf7fbd4f..5e54b93b0c 100644
--- a/Fltk/graphicWindow.cpp
+++ b/Fltk/graphicWindow.cpp
@@ -101,11 +101,21 @@ static void gmsh_models(Fl_Color c)
 #undef bl
 #undef el
 
+static int findGraphIndex(Fl_Widget *w)
+{
+  if(!w || !w->parent()) return 0;
+  for(unsigned int i = 0; i < GUI::instance()->graph.size(); i++)
+    if(GUI::instance()->graph[i]->win == w->parent())
+      return i;
+  return 0;
+}
+
 void status_xyz1p_cb(Fl_Widget *w, void *data)
 {
   const char *str = (const char*)data;
 
-  drawContext *ctx = GUI::instance()->graph[0]->gl->getDrawContext();
+  int index = findGraphIndex(w);
+  drawContext *ctx = GUI::instance()->graph[index]->gl->getDrawContext();
 
   if(!strcmp(str, "r")){ // rotate 90 degress around axis perp to the screen
     double axis[3] = {0., 0., 1.};
@@ -177,7 +187,8 @@ void status_xyz1p_cb(Fl_Widget *w, void *data)
   else if(!strcmp(str, "S")){ // mouse selection
     if(CTX.mouse_selection){
       opt_general_mouse_selection(0, GMSH_SET | GMSH_GUI, 0);
-      GUI::instance()->graph[0]->gl->cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE);
+      GUI::instance()->graph[index]->gl->cursor
+        (FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE);
     }
     else
       opt_general_mouse_selection(0, GMSH_SET | GMSH_GUI, 1);
@@ -223,7 +234,7 @@ void status_play_manual(int time, int step)
 static void status_play_cb(Fl_Widget *w, void *data)
 {
   static double anim_time;
-  GUI::instance()->graph[0]->setAnimButtons(0);
+  GUI::instance()->graph[findGraphIndex(w)]->setAnimButtons(0);
   stop_anim = 0;
   anim_time = GetTimeInSeconds();
   while(1) {
@@ -240,7 +251,7 @@ static void status_play_cb(Fl_Widget *w, void *data)
 static void status_pause_cb(Fl_Widget *w, void *data)
 {
   stop_anim = 1;
-  GUI::instance()->graph[0]->setAnimButtons(1);
+  GUI::instance()->graph[findGraphIndex(w)]->setAnimButtons(1);
 }
 
 static void status_rewind_cb(Fl_Widget *w, void *data)
@@ -267,7 +278,7 @@ static void status_stepforward_cb(Fl_Widget *w, void *data)
   status_play_manual(!CTX.post.anim_cycle, 1);
 }
 
-graphicWindow::graphicWindow(int fontsize)
+graphicWindow::graphicWindow(int fontsize, drawContext *ctx)
 {
   static bool first = true;
   if(first){
@@ -386,7 +397,7 @@ graphicWindow::graphicWindow(int fontsize)
   win->resizable(resbox);
   
   // opengl window
-  gl = new openglWindow(0, 0, width, glheight);
+  gl = new openglWindow(0, 0, width, glheight, 0, ctx);
   int mode = FL_RGB | FL_DEPTH | (CTX.db ? FL_DOUBLE : FL_SINGLE);
   if(CTX.antialiasing) mode |= FL_MULTISAMPLE;
   gl->mode(mode);
diff --git a/Fltk/graphicWindow.h b/Fltk/graphicWindow.h
index 266412126e..b5386e7239 100644
--- a/Fltk/graphicWindow.h
+++ b/Fltk/graphicWindow.h
@@ -18,7 +18,7 @@ class graphicWindow{
   Fl_Button *butt[12];
   Fl_Box *label[2];
  public:
-  graphicWindow(int fontsize);
+  graphicWindow(int fontsize, drawContext *ctx=0);
   void setAnimButtons(int mode);
   void checkAnimButtons();
 };
diff --git a/Fltk/openglWindow.cpp b/Fltk/openglWindow.cpp
index 072293ea6c..7ddd2ac4d4 100644
--- a/Fltk/openglWindow.cpp
+++ b/Fltk/openglWindow.cpp
@@ -67,19 +67,18 @@ static void lassoZoom(drawContext *ctx, mousePosition &click1, mousePosition &cl
   GUI::instance()->manip->update();
 }
 
-openglWindow::openglWindow(int x, int y, int w, int h, const char *l)
-  : Fl_Gl_Window(x, y, w, h, l)
+openglWindow::openglWindow(int x, int y, int w, int h, const char *l,
+                           drawContext *ctx)
+  : _ctx(ctx), Fl_Gl_Window(x, y, w, h, l)
 {
   addPointMode = lassoMode = selectionMode = false;
   _point[0] = _point[1] = _point[2] = 0.;
-  //double mat[3][3]={{1,0,0}, {0,1,0}, {0,0,10}};
-  //_ctx = new drawContext(new drawTransformScaled(mat));
-  _ctx = new drawContext();
+  if(!_ctx) _ctx = new drawContext();
 }
 
 openglWindow::~openglWindow()
 { 
-  delete _ctx; 
+  delete _ctx;
 }
 
 void openglWindow::draw()
@@ -105,7 +104,7 @@ void openglWindow::draw()
     if((w() != _ctx->viewport[2] - _ctx->viewport[0]) ||
        (h() != _ctx->viewport[3] - _ctx->viewport[1])) {
       GUI::instance()->setGraphicSize(_ctx->viewport[2] - _ctx->viewport[0],
-                          _ctx->viewport[3] - _ctx->viewport[1]);
+                                      _ctx->viewport[3] - _ctx->viewport[1]);
       glViewport(_ctx->viewport[0], _ctx->viewport[1],
                  _ctx->viewport[2], _ctx->viewport[3]);
     }
@@ -399,7 +398,7 @@ int openglWindow::handle(int event)
     }
     else{ // hover mode
       if(_curr.win[0] != _prev.win[0] || _curr.win[1] != _prev.win[1]){
-        GUI::instance()->graph[0]->gl->make_current();
+        make_current();
         std::vector<GVertex*> vertices;
         std::vector<GEdge*> edges;
         std::vector<GFace*> faces;
diff --git a/Fltk/openglWindow.h b/Fltk/openglWindow.h
index 5ab361fc2e..be0b060eb1 100644
--- a/Fltk/openglWindow.h
+++ b/Fltk/openglWindow.h
@@ -43,7 +43,8 @@ class openglWindow : public Fl_Gl_Window {
   int handle(int);
  public:
   bool addPointMode, lassoMode, selectionMode;
-  openglWindow(int x, int y, int w, int h, const char *l=0);
+  openglWindow(int x, int y, int w, int h, const char *l=0,
+               drawContext *ctx=0);
   ~openglWindow();
   drawContext *getDrawContext(){ return _ctx; }
 };
-- 
GitLab