Advertisement
acheong87

fltk.cpp

Mar 3rd, 2014
508
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 31.50 KB | None | 0 0
  1. /***************************************************************************
  2.  * fltk.cpp is part of Math Graphic Library
  3.  * Copyright (C) 2007-2014 Alexey Balakin <[email protected]>       *
  4.  *                                                                         *
  5.  *   This program is free software; you can redistribute it and/or modify  *
  6.  *   it under the terms of the GNU Library General Public License as       *
  7.  *   published by the Free Software Foundation; either version 3 of the    *
  8.  *   License, or (at your option) any later version.                       *
  9.  *                                                                         *
  10.  *   This program is distributed in the hope that it will be useful,       *
  11.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  12.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
  13.  *   GNU General Public License for more details.                          *
  14.  *                                                                         *
  15.  *   You should have received a copy of the GNU Library General Public     *
  16.  *   License along with this program; if not, write to the                 *
  17.  *   Free Software Foundation, Inc.,                                       *
  18.  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  19.  ***************************************************************************/
  20. #include <FL/Fl_Pixmap.H>
  21. #include <FL/fl_ask.H>
  22. #include <FL/Fl_Double_Window.H>
  23. #include <FL/fl_draw.H>
  24. #include <FL/Fl_File_Chooser.H>
  25. //#include <unistd.h>
  26. //-----------------------------------------------------------------------------
  27. #ifdef USE_GETTEXT
  28. #include <libintl.h>
  29. #else
  30. // Workaround for gcc 4.2
  31. #ifndef _LIBINTL_H
  32. #define gettext(x)  (x)
  33. #endif
  34. #endif
  35. //-----------------------------------------------------------------------------
  36. #include "mgl2/canvas_wnd.h"
  37. #include "mgl2/fltk.h"
  38. //-----------------------------------------------------------------------------
  39. #include "xpm/alpha_on.xpm"
  40. #include "xpm/light_on.xpm"
  41. #include "xpm/zoom_on.xpm"
  42. #include "xpm/show_on.xpm"
  43. #include "xpm/rotate_on.xpm"
  44. #include "xpm/show_sl.xpm"
  45. #include "xpm/next_sl.xpm"
  46. #include "xpm/prev_sl.xpm"
  47. #include "xpm/left_1.xpm"
  48. #include "xpm/right_1.xpm"
  49. #include "xpm/down_1.xpm"
  50. #include "xpm/norm_1.xpm"
  51. #include "xpm/zoom_1.xpm"
  52. #include "xpm/up_1.xpm"
  53. #include "xpm/alpha.xpm"
  54. #include "xpm/light.xpm"
  55. #include "xpm/zoom_in.xpm"
  56. #include "xpm/zoom_out.xpm"
  57. #include "xpm/rotate.xpm"
  58. #include "xpm/ok.xpm"
  59. #include "xpm/wire.xpm"
  60. //-----------------------------------------------------------------------------
  61. Fl_Pixmap xpm_a1(alpha_xpm), xpm_a2(alpha_on_xpm);
  62. Fl_Pixmap xpm_l1(light_on_xpm), xpm_l2(light_xpm);
  63. Fl_Pixmap xpm_z1(zoom_in_xpm), xpm_z2(zoom_on_xpm);
  64. Fl_Pixmap xpm_s1(show_sl_xpm), xpm_s2(show_on_xpm);
  65. Fl_Pixmap xpm_r1(rotate_xpm), xpm_r2(rotate_on_xpm);
  66. Fl_Pixmap xpm_wire(wire_xpm);
  67. //-----------------------------------------------------------------------------
  68. /// Class allows the window creation for displaying plot bitmap with the help of FLTK library
  69. /** NOTE!!! All frames are saved in memory. So animation with many frames require a lot memory and CPU time (for example, for mouse rotation).*/
  70. class mglCanvasFL : public mglCanvasWnd
  71. {
  72. public:
  73. using mglCanvasWnd::Window;
  74.     Fl_Window *Wnd;     ///< Pointer to window
  75.     Fl_MGLView *mgl;    ///< Pointer to MGL widget with buttons
  76.  
  77.     mglCanvasFL();
  78.     ~mglCanvasFL();
  79.  
  80.     /// Create a window for plotting. Now implemeted only for GLUT.
  81.     void Window(int argc, char **argv, int (*draw)(mglBase *gr, void *p), const char *title,
  82.                         void *par=NULL, void (*reload)(void *p)=NULL, bool maximize=false);
  83.     /// Switch on/off transparency (do not overwrite switches in user drawing function)
  84.     void ToggleAlpha();
  85.     /// Switch on/off lighting (do not overwrite switches in user drawing function)
  86.     void ToggleLight();
  87.     void ToggleRotate();    ///< Switch on/off rotation by mouse
  88.     void ToggleZoom();      ///< Switch on/off zooming by mouse
  89.     void ToggleNo();        ///< Switch off all zooming and rotation
  90.     void Update();          ///< Update picture by calling user drawing function
  91.     void Adjust();          ///< Adjust size of bitmap to window size
  92.     void GotoFrame(int d);  ///< Show arbitrary frame (use relative step)
  93.     void Animation();   ///< Run animation (I'm too lasy to change it)
  94. };
  95. //-----------------------------------------------------------------------------
  96. void MGL_EXPORT mgl_ask_fltk(const wchar_t *quest, wchar_t *res)
  97. {
  98.     static char buf[1024];  *res=0;
  99. #if FL_MINOR_VERSION>=3
  100.     fl_utf8fromwc(buf, 1024, quest, mgl_wcslen(quest)+1);
  101.     const char *str = fl_input("%s",buf,"");
  102.     if(str) fl_utf8towc(str, strlen(str)+1, res, 1024);
  103. #else
  104.     wcstombs(buf,quest,mgl_wcslen(quest)+1);
  105.     const char *str = fl_input("%s",buf,"");
  106.     MGL_TO_WCS(str,wcscpy(res,str));
  107. #endif
  108. }
  109. //-----------------------------------------------------------------------------
  110. //
  111. //      class Fl_MathGL
  112. //
  113. //-----------------------------------------------------------------------------
  114. Fl_MathGL::Fl_MathGL(int xx, int yy, int ww, int hh, const char *lbl) : Fl_Widget(xx,yy,ww,hh,lbl)
  115. {
  116.     gr = new mglCanvas;
  117.     tet=phi=x1=y1=0;    x2=y2=1;
  118.     zoom = rotate = false;
  119.     flag=x0=y0=xe=ye=0;
  120.     tet_val = phi_val = 0;
  121.     draw_par = 0;   draw_func = 0;  draw_cl = 0;
  122. }
  123. //-----------------------------------------------------------------------------
  124. Fl_MathGL::~Fl_MathGL() {   if(mgl_use_graph(gr,-1)<1)  mgl_delete_graph(gr);   }
  125. //-----------------------------------------------------------------------------
  126. void Fl_MathGL::set_graph(HMGL GR)
  127. {
  128.     mglCanvas *gg = dynamic_cast<mglCanvas *>(GR);
  129.     if(!gg) return;
  130.     if(mgl_use_graph(gr,-1)<1)  mgl_delete_graph(gr);
  131.     gr=gg;  mgl_use_graph(gg,1);
  132. }
  133. //-----------------------------------------------------------------------------
  134. void Fl_MathGL::draw()
  135. {
  136.     // TODO: add active points drawing here (from Qt)
  137.     const unsigned char *g = mgl_get_rgb(gr);
  138.     int i, ww=mgl_get_width(gr), hh=mgl_get_height(gr);
  139.     if(g)   fl_draw_image(g, x(), y(), ww, hh, 3);
  140.     if(flag&4)
  141.     {
  142.         char str[5]="0.0";
  143.         fl_color(192,192,192);
  144.         for(i=1;i<10;i++)
  145.         {
  146.             str[2] = '0'+10-i;  fl_draw(str,30,30+i*hh/10);
  147.             fl_line(30,30+i*hh/10,30+ww,30+i*hh/10);
  148.             str[2] = '0'+i; fl_draw(str,30+i*ww/10,30+hh);
  149.             fl_line(30+i*ww/10,30,30+i*ww/10,30+hh);
  150.         }
  151. //      if(*MouseBuf)   fl_draw(MouseBuf,30,50);
  152.     }
  153. }
  154. //-----------------------------------------------------------------------------
  155. void Fl_MathGL::update()
  156. {
  157.     if(draw_func || draw_cl)
  158.     {
  159.         mgl_reset_frames(gr);
  160.         if(mgl_get_flag(gr,MGL_CLF_ON_UPD)) mgl_set_def_param(gr);
  161.         mgl_set_alpha(gr,flag&1);   mgl_set_light(gr,flag&2);
  162.         if(tet_val) tet = tet_val->value();
  163.         if(phi_val) phi = phi_val->value();
  164.         mgl_zoom(gr,x1,y1,x2,y2);   mgl_view(gr,phi,0,tet);
  165.         setlocale(LC_NUMERIC, "C");
  166.         // use frames for quickly redrawing while adding/changing primitives
  167.         if(mgl_is_frames(gr))   mgl_new_frame(gr);
  168.         if(draw_func)   draw_func(gr, draw_par);    // drawing itself
  169.         else    if(draw_cl) {   mglGraph g(gr); draw_cl->Draw(&g);  }
  170.         if(mgl_is_frames(gr))   mgl_end_frame(gr);
  171.         setlocale(LC_NUMERIC, "");
  172.         const char *buf = mgl_get_mess(gr);
  173.         if(*buf)    fl_message("%s",buf);
  174.     }
  175.     if(mgl_get_width(gr)!=w() || mgl_get_height(gr)!=h())
  176.         size(mgl_get_width(gr), mgl_get_height(gr));
  177.     redraw();   Fl::flush();
  178. }
  179. //-----------------------------------------------------------------------------
  180. void Fl_MathGL::resize(int xx, int yy, int ww, int hh)
  181. {   Fl_Widget::resize(xx,yy,ww,hh); }
  182. //-----------------------------------------------------------------------------
  183. int Fl_MathGL::handle(int code)
  184. {
  185.     if(popup && code==FL_PUSH && Fl::event_button()==FL_RIGHT_MOUSE)
  186.     {
  187.         const Fl_Menu_Item *m = popup->popup(Fl::event_x(), Fl::event_y(), 0, 0, 0);
  188.         if(m)   m->do_callback(wpar, vpar);
  189.     }
  190.     else if(!zoom && !rotate && code==FL_PUSH && Fl::event_button()==FL_LEFT_MOUSE)
  191.     {
  192.         mglCanvasWnd *g=dynamic_cast<mglCanvasWnd *>(gr);
  193.         if(g && g->ClickFunc)   g->ClickFunc(draw_par);
  194.         if(mgl_get_flag(gr,MGL_SHOW_POS))
  195.         {
  196.             mglPoint p = gr->CalcXYZ(Fl::event_x()-x(), Fl::event_y()-y());
  197.             if(g)   g->LastMousePos = p;
  198.             char s[128];
  199.             snprintf(s,128,"x=%g, y=%g, z=%g",p.x,p.y,p.z);
  200.             draw(); fl_color(FL_BLACK);     fl_draw(s,40,70);
  201.         }
  202.     }
  203.     else if((!rotate && !zoom) || Fl::event_button()!=FL_LEFT_MOUSE)
  204.     {
  205.         if(code==FL_FOCUS || code==FL_UNFOCUS)  return 1;
  206.         if(code==FL_KEYUP)
  207.         {
  208.             int key=Fl::event_key();
  209.             if(!strchr(" .,wasdrfx",key))   return 0;
  210.             if(key==' ')    {   update();   return 1;   }
  211.             if(key=='w')
  212.             {
  213.                 tet += 10;
  214.                 if(tet_val) tet_val->value(tet);
  215.                 update();   return 1;
  216.             }
  217.             if(key=='s')
  218.             {
  219.                 tet -= 10;
  220.                 if(tet_val) tet_val->value(tet);
  221.                 update();   return 1;
  222.             }
  223.             if(key=='a')
  224.             {
  225.                 phi += 10;
  226.                 if(phi_val) phi_val->value(phi);
  227.                 update();   return 1;
  228.             }
  229.             if(key=='d')
  230.             {
  231.                 phi -= 10;
  232.                 if(phi_val) phi_val->value(phi);
  233.                 update();   return 1;
  234.             }
  235.             if(key=='x')
  236.             {
  237.                 mglCanvasFL *g=dynamic_cast<mglCanvasFL *>(gr);
  238.                 if(g && g->mgl->FMGL==this)
  239.                 {   g->Wnd->hide(); return 1;   }
  240.                 else    return 0;
  241. //              exit(0);
  242.             }
  243.             if(key==',')
  244.             {
  245.                 mglCanvasFL *g=dynamic_cast<mglCanvasFL *>(gr);
  246.                 if(g && g->mgl->FMGL==this)
  247.                 {   g->PrevFrame(); return 1;   }
  248.                 else    return 0;
  249.             }
  250.             if(key=='.')
  251.             {
  252.                 mglCanvasFL *g=dynamic_cast<mglCanvasFL *>(gr);
  253.                 if(g && g->mgl->FMGL==this)
  254.                 {   g->NextFrame(); return 1;   }
  255.                 else    return 0;
  256.             }
  257.             if(key=='r')
  258.             {   flag = (flag&2) + ((~(flag&1))&1);  update();   return 1;   }
  259.             if(key=='f')
  260.             {   flag = (flag&1) + ((~(flag&2))&2);  update();   return 1;   }
  261.         }
  262.         return 0;
  263.     }
  264.     else if(code==FL_PUSH)  {   xe=x0=Fl::event_x();    ye=y0=Fl::event_y();    }
  265.     else if(code==FL_DRAG)
  266.     {
  267.         xe=Fl::event_x();   ye=Fl::event_y();
  268.         mreal ff = 240./sqrt(mreal(w()*h()));
  269.         if(rotate)
  270.         {
  271.             phi += (x0-xe)*ff;
  272.             tet += (y0-ye)*ff;
  273.             if(phi>180) phi-=360;       if(phi<-180)    phi+=360;
  274.             if(tet>180) tet-=360;       if(tet<-180)    tet+=360;
  275.             if(tet_val) tet_val->value(tet);
  276.             if(phi_val) phi_val->value(phi);
  277.             x0 = xe;    y0 = ye;
  278.             update();
  279.         }
  280.         redraw();
  281.     }
  282.     else if(code==FL_RELEASE)
  283.     {
  284.         if(zoom)
  285.         {
  286.             int w1=w(),h1=h();
  287.             mreal _x1,_x2,_y1,_y2;
  288.             _x1 = x1+(x2-x1)*(x0-x())/mreal(w1);
  289.             _y1 = y2-(y2-y1)*(ye-y())/mreal(h1);
  290.             _x2 = x1+(x2-x1)*(xe-x())/mreal(w1);
  291.             _y2 = y2-(y2-y1)*(y0-y())/mreal(h1);
  292.             x1=_x1;     x2=_x2;     y1=_y1;     y2=_y2;
  293.             if(x1>x2)   {   _x1=x1; x1=x2;  x2=_x1; }
  294.             if(y1>y2)   {   _x1=y1; y1=y2;  y2=_x1; }
  295.             update();
  296.         }
  297.         else
  298.         {
  299.             if(tet_val) tet_val->value(tet);
  300.             if(phi_val) phi_val->value(phi);
  301.         }
  302.         redraw();
  303.     }
  304.     return 1;
  305. }
  306. //-----------------------------------------------------------------------------
  307. //
  308. //      class Fl_MGLView
  309. //
  310. //-----------------------------------------------------------------------------
  311. void Fl_MGLView::toggle(int &val, Fl_Button *b, const char *txt)
  312. {
  313.     val = 1-val;    b->value(val);
  314.     if(menu && txt && *txt)
  315.     {
  316.         Fl_Menu_Item *m = (Fl_Menu_Item *)menu->find_item(gettext(txt));
  317.         if(m && val)    m->set();
  318.         if(m && !val)   m->clear();
  319.     }
  320.     update();
  321. }
  322. //-----------------------------------------------------------------------------
  323. void Fl_MGLView::setoff(int &val, Fl_Button *b, const char *txt)
  324. {
  325.     val = 0;    b->value(val);
  326.     if(menu && txt && *txt)
  327.     {
  328.         Fl_Menu_Item *m = (Fl_Menu_Item *)menu->find_item(gettext(txt));
  329.         if(m && val)    m->set();
  330.         if(m && !val)   m->clear();
  331.     }
  332.     //update();
  333. }
  334. //-----------------------------------------------------------------------------
  335. void MGL_NO_EXPORT mgl_grid_cb(Fl_Widget*, void* v)
  336. {   if(v)   ((Fl_MGLView*)v)->toggle_grid();    }
  337. //-------------------------------------------------------------------------
  338. void MGL_NO_EXPORT mgl_alpha_cb(Fl_Widget*, void* v)    // alpha?xpm_a2:xpm_a1
  339. {   if(v)   ((Fl_MGLView*)v)->toggle_alpha();   }
  340. void mglCanvasFL::ToggleAlpha() {   Fl::lock(); mgl->toggle_alpha();    Fl::unlock();   }
  341. //-----------------------------------------------------------------------------
  342. void MGL_NO_EXPORT mgl_light_cb(Fl_Widget*, void* v)    // light?xpm_l2:xpm_l1
  343. {   if(v)   ((Fl_MGLView*)v)->toggle_light();   }
  344. void mglCanvasFL::ToggleLight() {   Fl::lock(); mgl->toggle_light();    Fl::unlock();   }
  345. //-----------------------------------------------------------------------------
  346. void MGL_NO_EXPORT mgl_norm_cb(Fl_Widget*, void* v)
  347. {
  348.     Fl_MGLView *e = (Fl_MGLView*)v; if(!e)  return;
  349.     e->setoff_rotate();         e->setoff_zoom();
  350.     e->FMGL->tet_val->value(0); e->FMGL->phi_val->value(0);
  351.     e->FMGL->set_zoom(0,0,1,1);
  352.     e->update();
  353. }
  354. void mglCanvasFL::ToggleNo()    {   Fl::lock(); mgl_norm_cb(0,mgl); Fl::unlock();   }
  355. //-----------------------------------------------------------------------------
  356. void MGL_NO_EXPORT mgl_zoom_cb(Fl_Widget*, void* v)
  357. {
  358.     Fl_MGLView *e = (Fl_MGLView*)v; if(!e)  return;
  359.     e->setoff_rotate(); e->toggle_zoom();
  360. }
  361. void mglCanvasFL::ToggleZoom()  {   Fl::lock(); mgl_zoom_cb(0,mgl); Fl::unlock();   }
  362. //-----------------------------------------------------------------------------
  363. void MGL_NO_EXPORT mgl_rotate_cb(Fl_Widget*, void* v)
  364. {
  365.     Fl_MGLView *e = (Fl_MGLView*)v; if(!e)  return;
  366.     e->setoff_zoom();   e->toggle_rotate();
  367. }
  368. void mglCanvasFL::ToggleRotate()    {   Fl::lock(); mgl_rotate_cb(0,mgl);   Fl::unlock();   }
  369. //-----------------------------------------------------------------------------
  370. void Fl_MGLView::update()
  371. {
  372.     FMGL->set_state(zoom_bt->value(), rotate_bt->value());
  373.     FMGL->set_flag(alpha + 2*light + 4*grid);
  374.     FMGL->update();
  375. }
  376. void MGL_NO_EXPORT mgl_draw_cb(Fl_Widget*, void* v)
  377. {   if(v)   ((Fl_MGLView*)v)->update(); }
  378. void mglCanvasFL::Update()      {   Fl::lock(); mgl->update();  Fl::unlock();   }
  379. //-----------------------------------------------------------------------------
  380. void MGL_NO_EXPORT mgl_export_png_cb(Fl_Widget*, void* v)
  381. {
  382.     char *fname = fl_file_chooser(gettext("Save File As?"), "*.png", 0);
  383.     if(!fname || !fname[0]) return;
  384.     mgl_write_png(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0);
  385. }
  386. //-----------------------------------------------------------------------------
  387. void MGL_NO_EXPORT mgl_export_bps_cb(Fl_Widget*, void* v)
  388. {
  389.     char *fname = fl_file_chooser(gettext("Save File As?"), "*.eps", 0);
  390.     if(!fname || !fname[0]) return;
  391.     mgl_write_bps(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0);
  392. }
  393. //-----------------------------------------------------------------------------
  394. void MGL_NO_EXPORT mgl_export_pngn_cb(Fl_Widget*, void* v)
  395. {
  396.     char *fname = fl_file_chooser(gettext("Save File As?"), "*.png", 0);
  397.     if(!fname || !fname[0]) return;
  398.     mgl_write_png_solid(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0);
  399. }
  400. //-----------------------------------------------------------------------------
  401. void MGL_NO_EXPORT mgl_export_jpeg_cb(Fl_Widget*, void* v)
  402. {
  403.     char *fname = fl_file_chooser(gettext("Save File As?"), "*.jpg", 0);
  404.     if(!fname || !fname[0]) return;
  405.     mgl_write_jpg(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0);
  406. }
  407. //-----------------------------------------------------------------------------
  408. void MGL_NO_EXPORT mgl_export_svg_cb(Fl_Widget*, void* v)
  409. {
  410.     char *fname = fl_file_chooser(gettext("Save File As?"), "*.svg", 0);
  411.     if(!fname || !fname[0]) return;
  412.     mgl_write_svg(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0);
  413. }
  414. //-----------------------------------------------------------------------------
  415. void MGL_NO_EXPORT mgl_export_eps_cb(Fl_Widget*, void* v)
  416. {
  417.     char *fname = fl_file_chooser(gettext("Save File As?"), "*.eps", 0);
  418.     if(!fname || !fname[0]) return;
  419.     mgl_write_eps(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0);
  420. }
  421. //-----------------------------------------------------------------------------
  422. void MGL_NO_EXPORT mgl_export_prc_cb(Fl_Widget*, void* v)
  423. {
  424.     char *fname = fl_file_chooser(gettext("Save File As?"), "*.prc", 0);
  425.     if(!fname || !fname[0]) return;
  426.     mgl_write_prc(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0,1);
  427. }
  428. //-----------------------------------------------------------------------------
  429. void MGL_NO_EXPORT mgl_export_tex_cb(Fl_Widget*, void* v)
  430. {
  431.     char *fname = fl_file_chooser(gettext("Save File As?"), "*.tex", 0);
  432.     if(!fname || !fname[0]) return;
  433.     mgl_write_tex(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0);
  434. }
  435. //-----------------------------------------------------------------------------
  436. void MGL_NO_EXPORT mgl_export_obj_cb(Fl_Widget*, void* v)
  437. {
  438.     char *fname = fl_file_chooser(gettext("Save File As?"), "*.obj", 0);
  439.     if(!fname || !fname[0]) return;
  440.     mgl_write_obj(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0,1);
  441. }
  442. //-----------------------------------------------------------------------------
  443. void MGL_NO_EXPORT mgl_export_off_cb(Fl_Widget*, void* v)
  444. {
  445.     char *fname = fl_file_chooser(gettext("Save File As?"), "*.off", 0);
  446.     if(!fname || !fname[0]) return;
  447.     mgl_write_off(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0,0);
  448. }
  449. //-----------------------------------------------------------------------------
  450. void MGL_NO_EXPORT mgl_export_stl_cb(Fl_Widget*, void* v)
  451. {
  452.     char *fname = fl_file_chooser(gettext("Save File As?"), "*.stl", 0);
  453.     if(!fname || !fname[0]) return;
  454.     mgl_write_stl(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0);
  455. }
  456. //-----------------------------------------------------------------------------
  457. void MGL_NO_EXPORT mgl_su_cb(Fl_Widget*, void* v)
  458. {
  459.     Fl_MGLView *e = (Fl_MGLView*)v; if(!e)  return;
  460.     mreal x1,x2,y1,y2,d;
  461.     e->FMGL->get_zoom(&x1,&y1,&x2,&y2);
  462.     d = (y2-y1)/3;  y1 -= d;    y2 -= d;
  463.     e->FMGL->set_zoom(x1,y1,x2,y2);
  464. }
  465. //-----------------------------------------------------------------------------
  466. void MGL_NO_EXPORT mgl_sd_cb(Fl_Widget*, void* v)
  467. {
  468.     Fl_MGLView *e = (Fl_MGLView*)v; if(!e)  return;
  469.     mreal x1,x2,y1,y2,d;
  470.     e->FMGL->get_zoom(&x1,&y1,&x2,&y2);
  471.     d = (y2-y1)/3;  y1 += d;    y2 += d;
  472.     e->FMGL->set_zoom(x1,y1,x2,y2);
  473. }
  474. //-----------------------------------------------------------------------------
  475. void MGL_NO_EXPORT mgl_sr_cb(Fl_Widget*, void* v)
  476. {
  477.     Fl_MGLView *e = (Fl_MGLView*)v; if(!e)  return;
  478.     mreal x1,x2,y1,y2,d;
  479.     e->FMGL->get_zoom(&x1,&y1,&x2,&y2);
  480.     d = (x2-x1)/3;  x1 -= d;    x2 -= d;
  481.     e->FMGL->set_zoom(x1,y1,x2,y2);
  482. }
  483. //-----------------------------------------------------------------------------
  484. void MGL_NO_EXPORT mgl_sl_cb(Fl_Widget*, void* v)
  485. {
  486.     Fl_MGLView *e = (Fl_MGLView*)v; if(!e)  return;
  487.     mreal x1,x2,y1,y2,d;
  488.     e->FMGL->get_zoom(&x1,&y1,&x2,&y2);
  489.     d = (x2-x1)/3;  x1 += d;    x2 += d;
  490.     e->FMGL->set_zoom(x1,y1,x2,y2);
  491. }
  492. //-----------------------------------------------------------------------------
  493. void MGL_NO_EXPORT mgl_sz_cb(Fl_Widget*, void* v)
  494. {
  495.     Fl_MGLView *e = (Fl_MGLView*)v; if(!e)  return;
  496.     mreal x1,x2,y1,y2,d;
  497.     e->FMGL->get_zoom(&x1,&y1,&x2,&y2);
  498.     d = (y2-y1)/4;  y1 += d;    y2 -= d;
  499.     d = (x2-x1)/4;  x1 += d;    x2 -= d;
  500.     e->FMGL->set_zoom(x1,y1,x2,y2);
  501. }
  502. //-----------------------------------------------------------------------------
  503. void MGL_NO_EXPORT mgl_so_cb(Fl_Widget*, void* v)
  504. {
  505.     Fl_MGLView *e = (Fl_MGLView*)v; if(!e)  return;
  506.     mreal x1,x2,y1,y2,d;
  507.     e->FMGL->get_zoom(&x1,&y1,&x2,&y2);
  508.     d = (y2-y1)/2;  y1 -= d;    y2 += d;
  509.     d = (x2-x1)/2;  x1 -= d;    x2 += d;
  510.     e->FMGL->set_zoom(x1,y1,x2,y2);
  511. }
  512. //-----------------------------------------------------------------------------
  513. void MGL_NO_EXPORT mgl_adjust_cb(Fl_Widget*, void*v)
  514. {   Fl_MGLView *e = (Fl_MGLView*)v; if(e)   e->adjust();    }
  515. void mglCanvasFL::Adjust()  {   Fl::lock(); mgl_adjust_cb(0,mgl);   Fl::unlock();   }
  516. //-----------------------------------------------------------------------------
  517. void MGL_NO_EXPORT mgl_oncemore_cb(Fl_Widget*, void*v)
  518. {   Fl_MGLView *e = (Fl_MGLView*)v; if(e && e->reload)  e->reload(e->par);  }
  519. //-----------------------------------------------------------------------------
  520. void MGL_NO_EXPORT mgl_quit_cb(Fl_Widget*, void*)   {   Fl::first_window()->hide(); }
  521. //-----------------------------------------------------------------------------
  522. void MGL_NO_EXPORT mgl_snext_cb(Fl_Widget*, void* v)
  523. {   Fl_MGLView *e = (Fl_MGLView*)v; if(e && e->next)    e->next(e->par);    }
  524. //-----------------------------------------------------------------------------
  525. void MGL_NO_EXPORT mgl_sprev_cb(Fl_Widget*, void* v)
  526. {   Fl_MGLView *e = (Fl_MGLView*)v; if(e && e->prev)    e->prev(e->par);    }
  527. //-----------------------------------------------------------------------------
  528. void MGL_NO_EXPORT mgl_time_cb(void *v)
  529. {
  530.     Fl_MGLView *e = (Fl_MGLView*)v;
  531.     if(!e || !e->is_sshow() || !e->next || !e->delay)   return;
  532.     e->next(e->par);
  533.     Fl::repeat_timeout(e->delay(e->par), mgl_time_cb, v);
  534. }
  535. //-----------------------------------------------------------------------------
  536. void MGL_NO_EXPORT mgl_sshow_cb(Fl_Widget *, void *v)
  537. {
  538.     Fl_MGLView *e = (Fl_MGLView*)v;
  539.     if(!e || !e->delay || !e->next) return;
  540.     e->toggle_sshow();
  541.     if(e->is_sshow())   Fl::add_timeout(e->delay(e->par), mgl_time_cb, v);
  542. }
  543. void mglCanvasFL::Animation()   {   Fl::lock(); mgl_sshow_cb(0,mgl);    Fl::unlock();   }
  544. void MGL_NO_EXPORT mgl_no_cb(Fl_Widget *, void *)   {}
  545. //-----------------------------------------------------------------------------
  546. Fl_Menu_Item pop_graph[20] = {
  547.     { gettext("Export"), 0, mgl_no_cb, 0, FL_SUBMENU,0,0,0,0},
  548.         { gettext("... as PNG"),    0, mgl_export_png_cb,0,0,0,0,0,0 },
  549.         { gettext("... as PNG (solid)"),    0, mgl_export_pngn_cb,0,0,0,0,0,0 },
  550.         { gettext("... as JPEG"),   0, mgl_export_jpeg_cb,0,0,0,0,0,0 },
  551.         { gettext("... as SVG"),    0, mgl_export_svg_cb,0,0,0,0,0,0 },
  552.         { gettext("... as vector EPS"), 0, mgl_export_eps_cb,0,0,0,0,0,0 },
  553.         { gettext("... as bitmap EPS"), 0, mgl_export_bps_cb, 0, FL_MENU_DIVIDER,0,0,0,0 },
  554.         { gettext("... as TeX"),    0, mgl_export_tex_cb,0,0,0,0,0,0 },
  555.         { gettext("... as OBJ"),    0, mgl_export_obj_cb,0,0,0,0,0,0 },
  556.         { gettext("... as PRC"),    0, mgl_export_prc_cb,0,0,0,0,0,0 },
  557.         { gettext("... as OFF"),    0, mgl_export_off_cb,0,0,0,0,0,0 },
  558.         { gettext("... as STL"),    0, mgl_export_stl_cb,0,0,0,0,0,0 },
  559.         { 0,0,0,0,0,0,0,0,0 },
  560.     { gettext("Copy graphics"), 0, 0, 0, FL_MENU_INACTIVE|FL_MENU_DIVIDER,0,0,0,0},
  561.     { gettext("Normal view"),   0, mgl_norm_cb,0,0,0,0,0,0 },
  562.     { gettext("Redraw plot"),   0, mgl_draw_cb,0,0,0,0,0,0 },
  563.     { gettext("Adjust size"),   0, mgl_adjust_cb,0,0,0,0,0,0 },
  564.     { gettext("Reload data"),   0, mgl_oncemore_cb,0,0,0,0,0,0 },
  565.     { 0,0,0,0,0,0,0,0,0 }
  566. };
  567. //-----------------------------------------------------------------------------
  568. Fl_MGLView::Fl_MGLView(int xx, int yy, int ww, int hh, const char *lbl) : Fl_Window(xx,yy,ww,hh,lbl)
  569. {
  570.     grid = alpha = light = sshow = 0;   menu = 0;
  571.     next = prev = reload = NULL;    delay = NULL;
  572.  
  573.     Fl_Button *o;
  574.     Fl_Group *g = new Fl_Group(0,30,435,30);
  575.  
  576.     alpha_bt = new Fl_Button(0, 1, 25, 25); alpha_bt->type(FL_TOGGLE_BUTTON);
  577.     alpha_bt->image(xpm_a1);    alpha_bt->callback(mgl_alpha_cb,this);
  578.     alpha_bt->tooltip(gettext("Switch on/off transparency in the picture"));
  579. //  alpha_bt->box(FL_PLASTIC_UP_BOX);       alpha_bt->down_box(FL_PLASTIC_DOWN_BOX);
  580.     light_bt = new Fl_Button(25, 1, 25, 25);    light_bt->type(FL_TOGGLE_BUTTON);
  581.     light_bt->image(xpm_l1);    light_bt->callback(mgl_light_cb,this);
  582.     light_bt->tooltip(gettext("Switch on/off lightning in the picture"));
  583. //  light_bt->box(FL_PLASTIC_UP_BOX);       light_bt->down_box(FL_PLASTIC_DOWN_BOX);
  584.     grid_bt = new Fl_Button(50, 1, 25, 25); grid_bt->type(FL_TOGGLE_BUTTON);
  585.     grid_bt->image(xpm_wire);   grid_bt->callback(mgl_grid_cb,this);
  586.     grid_bt->tooltip(gettext("Switch on/off grid drawing"));
  587.     //  grid_bt->box(FL_PLASTIC_UP_BOX);        grid_bt->down_box(FL_PLASTIC_DOWN_BOX);
  588.  
  589.     rotate_bt = new Fl_Button(80, 1, 25, 25);rotate_bt->type(FL_TOGGLE_BUTTON);
  590.     rotate_bt->image(xpm_r1);   rotate_bt->callback(mgl_rotate_cb,this);
  591.     rotate_bt->tooltip(gettext("Rotate picture by holding left mouse button"));
  592. //  rotate_bt->box(FL_PLASTIC_UP_BOX);      rotate_bt->down_box(FL_PLASTIC_DOWN_BOX);
  593.     zoom_bt = new Fl_Button(105, 1, 25, 25);    zoom_bt->type(FL_TOGGLE_BUTTON);
  594.     zoom_bt->image(xpm_z1); zoom_bt->callback(mgl_zoom_cb,this);
  595.     zoom_bt->tooltip(gettext("Zoom in selected region of the picture"));
  596. //  zoom_bt->box(FL_PLASTIC_UP_BOX);            zoom_bt->down_box(FL_PLASTIC_DOWN_BOX);
  597.     o = new Fl_Button(130, 1, 25, 25);      o->tooltip(gettext("Return picture to normal zoom"));
  598.     o->image(new Fl_Pixmap(zoom_out_xpm));  o->callback(mgl_norm_cb,this);
  599. //  o->box(FL_PLASTIC_UP_BOX);  o->down_box(FL_PLASTIC_DOWN_BOX);
  600.  
  601.     o = new Fl_Button(160, 1, 25, 25);  o->tooltip(gettext("Refresh the picture"));
  602.     o->image(new Fl_Pixmap(ok_xpm));    o->callback(mgl_draw_cb,this);
  603. //  o->box(FL_PLASTIC_UP_BOX);  o->down_box(FL_PLASTIC_DOWN_BOX);
  604.  
  605.     Fl_Counter *tet, *phi;
  606.     tet = new Fl_Counter(195, 1, 90, 25, 0);    tet->callback(mgl_draw_cb,this);
  607.     phi = new Fl_Counter(290, 1, 90, 25, 0);    phi->callback(mgl_draw_cb,this);
  608.     tet->lstep(10); tet->step(1);   tet->range(-180,180);
  609.     tet->tooltip(gettext("Theta angle (tilt z-axis)"));
  610.     phi->lstep(10); phi->step(1);   phi->range(-180,180);
  611.     phi->tooltip(gettext("Phi angle (rotate in x*y plane)"));
  612. //  tet->box(FL_PLASTIC_UP_BOX);    phi->box(FL_PLASTIC_UP_BOX);
  613.     g->end();   g->resizable(0);
  614.  
  615.     g = new Fl_Group(0,30,30,260);
  616.     o = new Fl_Button(1, 30, 25, 25);       o->tooltip(gettext("Shift the picture up"));
  617.     o->image(new Fl_Pixmap(up_1_xpm));      o->callback(mgl_su_cb,this);
  618. //  o->box(FL_PLASTIC_UP_BOX);  o->down_box(FL_PLASTIC_DOWN_BOX);
  619.     o = new Fl_Button(1, 55, 25, 25);       o->tooltip(gettext("Shift the picture left"));
  620.     o->image(new Fl_Pixmap(left_1_xpm));    o->callback(mgl_sl_cb,this);
  621. //  o->box(FL_PLASTIC_UP_BOX);  o->down_box(FL_PLASTIC_DOWN_BOX);
  622.     o = new Fl_Button(1, 80, 25, 25);       o->tooltip(gettext("Zoom in the picture"));
  623.     o->image(new Fl_Pixmap(zoom_1_xpm));    o->callback(mgl_sz_cb,this);
  624. //  o->box(FL_PLASTIC_UP_BOX);  o->down_box(FL_PLASTIC_DOWN_BOX);
  625.     o = new Fl_Button(1, 105, 25, 25);      o->tooltip(gettext("Zoom out the picture"));
  626.     o->image(new Fl_Pixmap(norm_1_xpm));    o->callback(mgl_so_cb,this);
  627. //  o->box(FL_PLASTIC_UP_BOX);  o->down_box(FL_PLASTIC_DOWN_BOX);
  628.     o = new Fl_Button(1, 130, 25, 25);      o->tooltip(gettext("Shift the picture right"));
  629.     o->image(new Fl_Pixmap(right_1_xpm));   o->callback(mgl_sr_cb,this);
  630. //  o->box(FL_PLASTIC_UP_BOX);  o->down_box(FL_PLASTIC_DOWN_BOX);
  631.     o = new Fl_Button(1, 155, 25, 25);      o->tooltip(gettext("Shift the picture down"));
  632.     o->image(new Fl_Pixmap(down_1_xpm));    o->callback(mgl_sd_cb,this);
  633. //  o->box(FL_PLASTIC_UP_BOX);  o->down_box(FL_PLASTIC_DOWN_BOX);
  634.  
  635.     o = new Fl_Button(1, 185, 25, 25);      o->tooltip(gettext("Show previous frame in slideshow"));
  636.     o->image(new Fl_Pixmap(prev_sl_xpm));   o->callback(mgl_sprev_cb,this);
  637. //  o->box(FL_PLASTIC_UP_BOX);  o->down_box(FL_PLASTIC_DOWN_BOX);
  638.     anim_bt = new Fl_Button(1, 210, 25, 25);    anim_bt->type(FL_TOGGLE_BUTTON);
  639.     anim_bt->image(xpm_s1); anim_bt->callback(mgl_sshow_cb,this);
  640.     anim_bt->tooltip(gettext("Run/Stop slideshow (graphics animation)"));
  641. //  anim_bt->box(FL_PLASTIC_UP_BOX);        anim_bt->down_box(FL_PLASTIC_DOWN_BOX);
  642.     o = new Fl_Button(1, 235, 25, 25);      o->tooltip(gettext("Show next frame in slideshow"));
  643.     o->image(new Fl_Pixmap(next_sl_xpm));   o->callback(mgl_snext_cb,this);
  644. //  o->box(FL_PLASTIC_UP_BOX);  o->down_box(FL_PLASTIC_DOWN_BOX);
  645.  
  646.     g->end();   g->resizable(0);
  647.  
  648.     scroll = new Fl_Scroll(30, 30, 800, 600);
  649.     //scroll->begin();
  650.     FMGL = new Fl_MathGL(30, 30, 800, 600);
  651.     FMGL->tet_val = tet;
  652.     FMGL->phi_val = phi;
  653.     FMGL->set_popup(pop_graph,FMGL,this);
  654.     scroll->end();
  655.     resizable(scroll);  end();
  656. }
  657. Fl_MGLView::~Fl_MGLView()   {}
  658. //-----------------------------------------------------------------------------
  659. //
  660. //      class mglCanvasFL
  661. //
  662. //-----------------------------------------------------------------------------
  663. mglCanvasFL::mglCanvasFL() : mglCanvasWnd() {   Wnd=0;  }
  664. mglCanvasFL::~mglCanvasFL()     {   if(Wnd) delete Wnd; }
  665. //-----------------------------------------------------------------------------
  666. void mglCanvasFL::GotoFrame(int d)
  667. {
  668.     int f = GetCurFig()+d;
  669.     if(f>=GetNumFig())  f = 0;
  670.     if(f<0) f = GetNumFig()-1;
  671.     if(GetNumFig()>0 && d)  {   SetCurFig(f);   mgl->FMGL->redraw();    }
  672. }
  673. //-----------------------------------------------------------------------------
  674. void MGL_NO_EXPORT mgl_fl_next(void *v) {   ((mglCanvasWnd*)v)->NextFrame();    }   ///< Callback function for next frame
  675. void MGL_NO_EXPORT mgl_fl_prev(void *v) {   ((mglCanvasWnd*)v)->PrevFrame();    }   ///< Callback function for prev frame
  676. void MGL_NO_EXPORT mgl_fl_reload(void *v)   {   ((mglCanvasWnd*)v)->ReLoad();   }       ///< Callback function for reloading
  677. mreal MGL_NO_EXPORT mgl_fl_delay(void *v)   {   return ((mglCanvasWnd*)v)->GetDelay();  }   ///< Callback function for delay
  678. //-----------------------------------------------------------------------------
  679. void MGL_EXPORT mgl_makemenu_fltk(Fl_Menu_ *m, Fl_MGLView *w)
  680. {
  681.     m->add("Graphics/Alpha", "^t", mgl_alpha_cb, w, FL_MENU_TOGGLE);
  682.     m->add("Graphics/Light", "^l", mgl_light_cb, w, FL_MENU_TOGGLE);
  683.     m->add("Graphics/Grid", "^g", mgl_grid_cb, w, FL_MENU_TOGGLE|FL_MENU_DIVIDER);
  684.  
  685.     m->add("Graphics/Restore", "^ ", mgl_norm_cb, w);
  686.     m->add("Graphics/Redraw", "f5", mgl_draw_cb, w);
  687.     m->add("Graphics/Adjust size", "f6", mgl_adjust_cb, w);
  688.     m->add("Graphics/Reload data", "f9", mgl_oncemore_cb, w);
  689.     //TODO  m->add("Graphics/Stop", "f7", mgl_stop_cb, w);
  690.     //TODO  m->add("Graphics/Copy graphics","+^c", mgl_copyimg_cb, w);
  691.  
  692.     m->add("Graphics/Export/as PNG", "#p", mgl_export_png_cb, w);
  693.     m->add("Graphics/Export/as solid PNG", "#f", mgl_export_pngn_cb, w);
  694.     m->add("Graphics/Export/as JPEG", "#j", mgl_export_jpeg_cb, w);
  695.     m->add("Graphics/Export/as SVG", "#s", mgl_export_svg_cb, w);
  696.     m->add("Graphics/Export/as vector EPS", "#e", mgl_export_eps_cb, w);
  697.     m->add("Graphics/Export/as bitmap EPS", "", mgl_export_bps_cb, w);
  698.  
  699.     m->add("Graphics/Animation/Slideshow", "^f5", mgl_sshow_cb, w, FL_MENU_TOGGLE);
  700.     m->add("Graphics/Animation/Next frame", "#<", mgl_snext_cb, w);
  701.     m->add("Graphics/Animation/Prev frame", "#>", mgl_sprev_cb, w);
  702.     //TODO  m->add("Graphics/Animation/Setup", "", mgl_ssetup_cb, w);
  703. }
  704. //-----------------------------------------------------------------------------
  705. void mglCanvasFL::Window(int argc, char **argv, int (*draw)(mglBase *gr, void *p), const char *title, void *par, void (*reload)(void *p), bool maximize)
  706. {
  707.     Fl::lock();
  708.     SetDrawFunc(draw, par, reload);
  709.     if(Wnd) {   Wnd->label(title);  Wnd->show();    return; }
  710.  
  711.     Wnd = new Fl_Double_Window(830,660,title);
  712.  
  713.     mgl = new Fl_MGLView(0,30,830,630);     mgl->par = this;
  714.  
  715.     mgl->menu = new Fl_Menu_Bar(0, 0, 830, 30);
  716.     mgl_makemenu_fltk(mgl->menu, mgl);
  717.  
  718.     mgl->next = mgl_fl_next;    mgl->reload = mgl_fl_reload;
  719.     mgl->prev = mgl_fl_prev;    mgl->delay= mgl_fl_delay;
  720.     mgl->FMGL->set_graph(this);
  721.     mgl->FMGL->set_draw(draw, par);
  722.  
  723.     Wnd->end();
  724.     Wnd->resizable(mgl);    //w->graph);
  725.  
  726.     if(maximize)
  727.     {
  728.         int x,y,w,h;
  729.         Fl::screen_xywh(x,y,w,h);
  730.         Wnd->resize(x,y,w,h);
  731.         Adjust();
  732.     }
  733.  
  734.     char *tmp[1];   tmp[0]=new char[1]; tmp[0][0]=0;
  735.     Wnd->show(argv ? argc:0, argv ? argv:tmp);
  736.     delete []tmp[0];
  737. }
  738. //-----------------------------------------------------------------------------
  739. HMGL MGL_EXPORT mgl_create_graph_fltk(int (*draw)(HMGL gr, void *p), const char *title, void *par, void (*load)(void *p))
  740. {
  741.     mglCanvasFL *g = new mglCanvasFL;
  742.     g->Window(0,0,draw,title,par,load);
  743.     return g;
  744. }
  745. int MGL_EXPORT mgl_fltk_run()       {   return Fl::run();   }
  746. //-----------------------------------------------------------------------------
  747. uintptr_t MGL_EXPORT mgl_create_graph_fltk_(const char *title, int l)
  748. {
  749.     char *s = new char[l+1];    memcpy(s,title,l);  s[l]=0;
  750.     uintptr_t t = uintptr_t(mgl_create_graph_fltk(0,s,0,0));
  751.     delete []s; return t;
  752. }
  753. int MGL_EXPORT mgl_fltk_run_()  {   return mgl_fltk_run();  }
  754. //-----------------------------------------------------------------------------
  755. MGL_NO_EXPORT void *mgl_fltk_tmp(void *)
  756. {   mgl_fltk_run(); return 0;   }
  757. //-----------------------------------------------------------------------------
  758. int MGL_EXPORT mgl_fltk_thr()       // NOTE: Qt couldn't be running in non-primary thread
  759. {
  760. #if MGL_HAVE_PTHREAD
  761.     static pthread_t thr;
  762.     pthread_create(&thr,0,mgl_fltk_tmp,0);
  763.     pthread_detach(thr);
  764. #endif
  765.     return 0;   // stupid, but I don't want keep result returned by Fl::Run()
  766. }
  767. //-----------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement