1 // -*- mode:C++ ; compile-command: "g++ -I.. -g -c Graph.cc" -*-
2 #ifndef _GRAPH_H
3 #define _GRAPH_H
4 #ifdef HAVE_CONFIG_H
5 #include "config.h"
6 #endif
7 #ifndef IN_GIAC
8 #include <giac/giac.h>
9 #else
10 #include "giacPCH.h"
11 #include "giac.h"
12 #endif
13 #include <fstream>
14 #ifdef HAVE_SYS_TIME_H
15 #include <sys/time.h>
16 #else
17 #define clock_t int
18 #define clock() 0
19 #endif
20 #ifdef HAVE_LIBFLTK
21 #include <FL/Fl_Menu.H>
22 #include <FL/Fl_Window.H>
23 #include <FL/Fl_Tile.H>
24 #include <FL/Fl_Button.H>
25 #include <FL/Fl_Text_Buffer.H>
26 #include <FL/Fl_Text_Editor.H>
27 #include <FL/Fl_Value_Slider.H>
28 #include <FL/Fl_Counter.H>
29 #include <FL/Fl_Check_Button.H>
30 #endif
31 #ifdef HAVE_LC_MESSAGES
32 #include <locale.h>
33 #endif
34 #include <giacintl.h>
35 #include "Xcas1.h"
36 #include "Input.h"
37 #include "Editeur.h"
38 #include <string>
39 
40 #ifndef NO_NAMESPACE_XCAS
41 namespace xcas {
42 #endif // ndef NO_NAMESPACE_XCAS
43 
44 #ifdef HAVE_LIBFLTK
45 
46   // Locales initialization, should be done before history.o is loaded
47 
48   std::string & xcas_locale();
49   class objet_bidon{
50   public:
51     objet_bidon();
52   };
53   // extern objet_bidon * mon_objet_bidon_ptr;
54 
55   void xcas_color(int color,bool dim3=false);
56 
57   int plotparam_dialog(Fl_Widget * spread_ptr,std::string & arg,int modeplot);
58   std::string printstring(const giac::gen & g,const giac::context * contextptr);
59   void round3(double & x,double xmin,double xmax);
60 
61   extern bool do_helpon;// true if Xcas_automatic_completion_browser enabled
62 
63   enum extended_colors {
64     dark_blue_color=0x0f,
65     dark_green_color =0x3d,
66     braun_color=0x40,
67     orange_color=0x5a
68   };
69 
70   // quaternion struct for more intuitive rotations
71   struct quaternion_double {
72     double w,x,y,z;
quaternion_doublequaternion_double73     quaternion_double():w(1),x(0),y(0),z(0) {};
74     quaternion_double(double theta_x,double theta_y,double theta_z);
quaternion_doublequaternion_double75     quaternion_double(double _w,double _x,double _y,double _z):w(_w),x(_x),y(_y),z(_z) {};
norm2quaternion_double76     double norm2() const { return w*w+x*x+y*y+z*z;}
77   };
78 
79   quaternion_double operator * (const quaternion_double & q,const quaternion_double & q2);
80 
81   void get_axis_angle_deg(const quaternion_double & q,double &x,double &y,double & z, double &theta); // q must be a quaternion of unit norm, theta is in deg
82 
83   // Euler angle in degrees
84   quaternion_double euler_deg_to_quaternion_double(double a,double b,double c);
85 
86   std::ostream & operator << (std::ostream & os,const quaternion_double & q);
87 
88   // end quaternion utilities
89   // FLTK Drawing function with clipping checks,
90   // delta_i and delta_j should be 0
91   void check_fl_draw(const char * ch,int i0,int j0,int imin,int jmin,int di,int dj,int delta_i,int delta_j);
92   void check_fl_point(int i0,int j0,int imin,int jmin,int di,int dj,int delta_i,int delta_j);
93   void check_fl_rect(int i0,int j0,int i1,int j1,int imin,int jmin,int di,int dj,int delta_i,int delta_j);
94   void check_fl_rectf(int i0,int j0,int i1,int j1,int imin,int jmin,int di,int dj,int delta_i,int delta_j);
95   void check_fl_line(int i0,int j0,int i1,int j1,int imin,int jmin,int di,int dj,int delta_i,int delta_j);
96 
97   class Graph2d3d;
98   extern Fl_Menu_Item Graph2d3d_menu[];
99   extern Fl_Menu_Item Figure_menu[];
100   extern std::vector<Graph2d3d *> animations; // list of pointer to graph widgets
101 
102   class Mouse_Position:public Fl_Widget {
103   public:
104     Graph2d3d * graphic ;
Mouse_Position(int x,int y,int w,int h,Graph2d3d * g)105     Mouse_Position(int x,int y,int w,int h,Graph2d3d * g):Fl_Widget(x,y,w,h),graphic(g) { box(FL_FLAT_BOX); }
106     virtual FL_EXPORT void draw();
107   };
108 
109   struct window_xyz {
110     double xmin,xmax,ymin,ymax,zmin,zmax;
window_xyzwindow_xyz111     window_xyz():xmin(-5),xmax(5),ymin(-5),ymax(5),zmin(-5),zmax(5) {};
window_xyzwindow_xyz112     window_xyz(double x,double X,double y,double Y,double z,double Z):xmin(x),xmax(X),ymin(y),ymax(Y),zmin(z),zmax(Z) {};
113   };
114 
115   giac::gen add_attributs(const giac::gen & g,int couleur_,const giac::context *) ;
116   int change_line_type(int & res,bool show_approx,bool & approx,const std::string & title,bool dim3,bool & formel,bool & untranslate,bool del,int fontsize);
117 
118   class Graph2d3d:public Fl_Widget {
119   public:
120     int push_i,push_j,current_i,current_j,cursor_point_type; // position of mouse push/drag
121   protected:
122     double push_depth,current_depth;
123     bool pushed; // true when mode==0 and push has occured
124     bool in_area; // true if the mouse is in the area, updated by handle
125     int mode; // 0 pointer, 1 1-arg, 2 2-args, etc.
126     // plot_tmp=function_tmp(args_tmp) or function_final(args_tmp)
127     // depends whether args.tmp.size()==mode
128     giac::gen function_tmp,function_final,args_push;
129     giac::vecteur args_tmp; // WARNING should only contain numeric value
130     unsigned args_tmp_push_size;
131   public:
132     std::vector<std::string> args_help;
133     bool no_handle; // disable mouse handling
134     bool show_mouse_on_object; // FL_MOVE always handled or not
135     unsigned display_mode ;
136     // bit0=1 plot_instructions, bit1=1 animations_instruction
137     // bit2=1 glFrustum/glOrtho, bit3=1 GL_LIGHTING, bit4=1 GL_FLAT,
138     // bit5=GL_BLEND, bit6=trace, bit7=1 move frame disabled
139     // bit8=1 framebox, bit9=1 triedre
140     // bit10=1 logplot 2d x, bit11=1 logplot 2d y, bit12=1 reserved for logplot 3d z
141     double window_xmin,window_xmax,window_ymin,window_ymax,window_zmin,window_zmax;
142     std::vector<window_xyz> history;
143     int history_pos;
144     quaternion_double q;
145     int legende_size;
146     double ylegende;
147     // Fl_Tile * mouse_param_group ;
148     Fl_Group * mouse_param_group ;
149     Mouse_Position * mouse_position;
150     Fl_Group * param_group ;
151     Fl_Group * button_group ;
152     Fl_Menu_Bar * menubar;
153     History_Pack * hp;
154     std::string title,x_axis_name,x_axis_unit,y_axis_name,y_axis_unit,z_axis_name,z_axis_unit,fcnfield,fcnvars;
155     int npixels; // max # of pixels distance for click
156     int show_axes,show_names;
157     giac::vecteur plot_instructions,animation_instructions,trace_instructions ;
158     double animation_dt; // rate for animated plot
159     bool paused;
160     struct timeval animation_last; // clock value at last display
161     int animation_instructions_pos;
162     int rotanim_type,rotanim_danim,rotanim_nstep;
163     double rotanim_rx,rotanim_ry,rotanim_rz,rotanim_tstep;
164     int last_event;
165     double x_tick,y_tick,z_tick;
166     int couleur; // used for new point creation in geometry
167     bool approx; // exact or approx click mouse?
168     std::vector<int> selected; // all items selected in plot_instructions
169     giac::gen drag_original_value,drag_name;
170     int hp_pos; // Position in hp for modification
171     bool moving,moving_frame;
172     // 3-d light information
173     float light_x[8],light_y[8],light_z[8],light_w[8];
174     float light_diffuse_r[8],light_diffuse_g[8],light_diffuse_b[8],light_diffuse_a[8];
175     float light_specular_r[8],light_specular_g[8],light_specular_b[8],light_specular_a[8];
176     float light_ambient_r[8],light_ambient_g[8],light_ambient_b[8],light_ambient_a[8];
177     float light_spot_x[8],light_spot_y[8],light_spot_z[8],light_spot_w[8];
178     float light_spot_exponent[8],light_spot_cutoff[8];
179     float light_0[8],light_1[8],light_2[8];
180     bool light_on[8];
181     int ntheta,nphi; // default discretization params for sphere drawing
182     std::pair<Fl_Image *,Fl_Image *> * background_image; // 2-d only
183     int x_axis_color,y_axis_color,z_axis_color;
184     Graph2d3d(int x,int y,int w,int h,const char * l,double xmin,double xmax,double ymin,double ymax,double zmin,double zmax,double ortho,History_Pack * hp_);
185     Graph2d3d(int x,int y,int w,int h,const char * l=0,History_Pack * hp_=0);
186     double find_eps(); // find value of a small real wrt the current graph
187     void update_infos(const giac::gen & g,const giac::context * contextptr);
188     virtual void zoom(double d);
189     virtual void zoomx(double d,bool round=false);
190     virtual void zoomy(double d,bool round=false);
191     virtual void zoomz(double d,bool round=false);
192     virtual void orthonormalize();
193     virtual void autoscale(bool fullview=false);
194     virtual void find_ylegende();
195     virtual void up(double d);
196     virtual void down(double d);
197     virtual void up_z(double d);
198     virtual void down_z(double d);
199     virtual void left(double d);
200     virtual void right(double d);
201     virtual void move_cfg(int i); // moves forward/backward in cfg history
202     virtual void push_cfg(); // save current config
203     virtual void clear_cfg(); // reset history config
204     virtual void config(); // show window for WX/Y/ortho/axis cfg
205     virtual void config_light(unsigned i);
206     virtual void reset_light(unsigned i);
207     virtual void set_axes(int b);
208     void glequal(bool equal);
209     void copy(const Graph2d3d & gr);
210     void add_mouse_param_group(int x,int y,int w,int h);
211     virtual void do_handle(const giac::gen & g);
212     // if pos>=0, then update clears plot_instructions from pos included
213     // except if the i-th child is a parameter
214     void update(Fl_Group * pack,int pos=-1);
215     void clear(unsigned pos=0); // clear starting at position pos
216     // add plot_instructions from widgets
217     void add(const Fl_Widget * wid,int pos=0);
218     void add(const giac::gen & e);
219     void add(const giac::vecteur & v);
220     void autoname_plus_plus();
221     virtual FL_EXPORT int handle(int);
222     virtual int in_handle(int);
223     int handle_mouse(int);
224     int handle_keyboard(int);
225     int geo_handle(int event);
226     virtual const char * latex(const char * filename);
227     giac::gen geometry_round(double x,double y,double z,double eps,giac::gen & original,int & pos,bool selectfirstlevel=false,bool setscroller=false) ;
228     virtual void geometry_round(double x,double y,double z,double eps,giac::gen & tmp,const giac::context *) ;
229     giac::vecteur selection2vecteur(const std::vector<int> & v);
230     void set_mode(const giac::gen & f_tmp,const giac::gen & f_final,int m);
231     virtual void find_xyz(double i,double j,double depth,double & x,double & y,double & z);
232     void find_title_plot(giac::gen & title_tmp,giac::gen & plot_tmp,const giac::context * contextptr);
233     void change_attributs();
234     void change_attributs(int hp_pos);
235     void resize_mouse_param_group(int W);
236     virtual void resize(int X,int Y,int W,int H);
237     virtual ~Graph2d3d();
238     giac::vecteur animate(int nframes);
239     std::string current_config();
240     // return a sequence of graphic objects, ready for animation
241     void adjust_cursor_point_type();
242   };
243 
244   class Graph2d:public Graph2d3d {
245   protected:
246   public:
247     double orthonormal_factor;
248     giac::gen waiting_click_value;
249     bool waiting_click;
250     void in_draw(int x_clip,int y_clip,int w_clip,int h_clip,int & vertical_pixels);
251     virtual FL_EXPORT void draw();
252     int common_in_handle(int event);
253     virtual int in_handle(int);
254     virtual void orthonormalize();
255     void find_xy(double i,double j,double & x,double & y) const ;
256     bool findij(const giac::gen & e0,double x_scale,double y_scale,double & i0,double & j0,const giac::context * contextptr) const ;
257     Graph2d(int x,int y,int w,int h,const char * l=0,History_Pack * hp_=0);
258     virtual const char * latex(const char * filename);
259     virtual void find_xyz(double i,double j,double depth,double & x,double & y,double & z);
260     virtual void geometry_round(double x,double y,double z,double eps,giac::gen & tmp,const giac::context *) ;
261     int mouse_rescale();
262   };
263 
264   Graph2d3d * find_graph2d3d(Fl_Widget * wid);
265 
266   // find how to move position for legende drawing
267   void find_dxdy(const std::string & legendes,int labelpos,int labelsize,int & dx,int & dy);
268   std::string print_color(int couleur);
269 
270   int figure_param_dialog(Fl_Widget * f,bool adjust,double & tmin,double & tmax,double & tcurrent,double & tstep,std::string & name,bool symb,std::string & tmp);
271 
272   giac::gen geometry_round_numeric(double x,double y,double eps,bool approx);
273   giac::gen geometry_round_numeric(double x,double y,double z,double eps,bool approx);
274 
275   // Should be inside a Fl_Tile (1st element is a History_Pack
276   // with Multiline_Input and
277   // 2nd element is a Geo2d object and 3rd element a Fl_Pack of Parameters
278   class Geo2d:public Graph2d {
279   public:
280     virtual FL_EXPORT void draw();
281     virtual int in_handle(int event);
282     Geo2d(int x,int y,int w,int h,History_Pack * _hp=0,const char * l=0);
283   };
284 
285   History_Pack * geo_find_history_pack(Fl_Widget * wid);
286 
287   class Line_Type:public Fl_Button {
288     int line_type_;
289     bool show_pnt_,show_line_,show_text_,show_poly_;
290   public:
291     Line_Type(int x,int y,int w,int h,int lt=0);
292     void line_type(int l);
line_type()293     int line_type() const { return line_type_; }
show_pnt(bool b)294     void show_pnt(bool b){ show_pnt_=b; redraw(); }
show_pnt()295     bool show_pnt(){ return show_pnt_; }
show_line(bool b)296     void show_line(bool b){ show_line_=b; redraw(); }
show_line()297     bool show_line(){ return show_line_; }
show_text(bool b)298     void show_text(bool b){ show_text_=b; redraw(); }
show_text()299     bool show_text(){ return show_text_; }
show_poly(bool b)300     void show_poly(bool b){ show_poly_=b; redraw(); }
show_poly()301     bool show_poly(){ return show_poly_; }
302     virtual FL_EXPORT void draw();
303   };
304 
305   class Figure:public Fl_Tile {
306   public:
307     Graph2d3d * geo;
308     Fl_Button * name;
309     char * namestr;
310     Fl_Output * mode;
311     Fl_Button * couleur;
312     Line_Type * lt;
313     Fl_Group * barre;
314     xcas::HScroll * s;
315     Fl_Check_Button * checkdisp;
316     Fl_Window * win;
317     int disposition;
318     Figure(int X,int Y,int W,int H,int L,bool dim3=false);
319     void save_figure_as(const std::string & s);
320     std::string latex_save_figure();
321     void rename(const std::string & s);
322     virtual void resize(int X,int Y,int W,int H,double dhp=0.25,double dgeo=0.5,double dmp=0.25);
323     virtual int handle(int event);
324     virtual void draw();
325   };
326 
327   std::string figure_insert(Figure * f);
328 
329   void gen_value_slider_cb(Fl_Widget * widget,void *);
330 
331   class Gen_Value_Slider:public Fl_Counter {
332   public:
333     int pos;
334     std::string paramname;
335     Gen_Value_Slider(int x,int y,int w,int h,int _pos,double m,double M,double mystep,const std::string & pname);
336     // adjust history level to the slider value, and eval history pack
337     // if eval_hp is true
338     void adjust(bool );
339     virtual int handle(int event);
340   };
341 
342   Gen_Value_Slider * parameter2slider(const giac::gen & e,const giac::context *);
343 
344   class Turtle:public Fl_Widget {
345   public:
346     virtual FL_EXPORT void draw();
347     virtual FL_EXPORT void indraw();
348     virtual FL_EXPORT int handle(int);
349     std::vector<giac::logo_turtle> * turtleptr;
350     int legende_size;
351     int turtlex,turtley; // Turtle translate
352     double turtlezoom; // Zoom factor for turtle screen
353     int maillage; // 0 (none), 1 (square), 2 (triangle), bit3 used for printing
354     bool redraw_cap_only;
355     int push_x,push_y;
Fl_Widget(x,y,w,h,l)356     Turtle(int x,int y,int w,int h,const char * l=0): Fl_Widget(x,y,w,h,l),turtleptr(0),legende_size(giac::LEGENDE_SIZE),turtlex(0),turtley(0),turtlezoom(1),maillage(1),redraw_cap_only(false) {};
357     std::string latex_save_figure();
358     const char * latex(const char * filename_) const ;
359     ~Turtle();
360   };
361 
362   class Editeur;
363 
364   class Logo:public Fl_Tile {
365   public:
366     History_Pack * hp;
367     Turtle * t;
368     Fl_Group * button_group;
369     Editeur * ed;
370     Fl_Menu_Bar * menubar ;
371     int scroll_position;
372     Logo(int X,int Y,int W,int H,int L);
373     virtual void resize(int X,int Y,int W,int H);
374     virtual void draw();
375     virtual int handle(int);
376   };
377 
378 
379   std::ostream & fltk_fl_widget_archive_function(std::ostream & os,void * ptr);
380   giac::gen fltk_fl_widget_unarchive_function(std::istream & os);
381   std::string fltk_fl_widget_texprint_function(void * ptr);
382   giac::gen fltk_fl_widget_updatepict_function(const giac::gen &g);
383 
384   // If an auto-recovery file is found in s directory, returns true
385   // and sets newest to the filename
386   bool has_autorecover_data(const std::string & s,std::string & newest);
387 
388   // for xyztrange to change focused graphic config
389   giac::gen Xcas_xyztrange(const giac::gen & g,const giac::context *);
390   Figure * find_figure(Fl_Widget * widget);
391 
392   class BorderBox:public Fl_Box {
393   public:
BorderBox(int X,int Y,int W,int H)394     BorderBox(int X,int Y,int W,int H):Fl_Box(X,Y,W,H,"") {}
395     virtual int handle(int event);
396   };
397 
398 #endif // HAVE_LIBFLTK
399 
400 #ifndef NO_NAMESPACE_XCAS
401 } // namespace xcas
402 #endif // ndef NO_NAMESPACE_XCAS
403 
404 #endif // _GRAPH_H
405