35 #if defined (HAVE_CONFIG_H)
46 #if defined (HAVE_FLTK)
48 #if defined (HAVE_X_WINDOWS)
49 # include <X11/Xlib.h>
58 # define WIN32_LEAN_AND_MEAN
62 #include <FL/Fl_Box.H>
63 #include <FL/Fl_Button.H>
64 #include <FL/Fl_Choice.H>
65 #include <FL/Fl_File_Chooser.H>
66 #include <FL/Fl_Gl_Window.H>
68 #include <FL/Fl_Menu_Bar.H>
69 #include <FL/Fl_Menu_Button.H>
70 #include <FL/Fl_Output.H>
71 #include <FL/Fl_Window.H>
72 #include <FL/fl_ask.H>
73 #include <FL/fl_draw.H>
95 #define FLTK_GRAPHICS_TOOLKIT_NAME "fltk"
97 const char* help_text =
"\
106 mouse wheel - zoom\n\
107 right drag - rectangle zoom\n\
108 left double click - autoscale\n\
111 class OpenGL_fltk :
public Fl_Gl_Window
114 OpenGL_fltk (
int xx,
int yy,
int ww,
int hh,
double num)
115 : Fl_Gl_Window (xx, yy, ww, hh, 0),
number (num), renderer (),
116 in_zoom (
false), zoom_box ()
118 #if defined (HAVE_OPENGL)
120 mode (FL_DEPTH | FL_DOUBLE | FL_MULTISAMPLE);
126 ~OpenGL_fltk (
void) { }
135 bool zoom (
void) {
return in_zoom; }
136 void set_zoom_box (
const Matrix& zb) { zoom_box = zb; }
145 void resize (
int xx,
int yy,
int ww,
int hh)
147 #if defined (HAVE_OPENGL)
149 Fl_Gl_Window::resize (xx, yy, ww, hh);
159 bool renumber (
double new_number)
181 #if defined (HAVE_OPENGL)
185 glMatrixMode (GL_PROJECTION);
187 glViewport (0, 0,
w (),
h ());
203 void zoom_box_vertex (
void)
205 #if defined (HAVE_OPENGL)
207 glVertex2d (zoom_box(0),
h () - zoom_box(1));
208 glVertex2d (zoom_box(0),
h () - zoom_box(3));
209 glVertex2d (zoom_box(2),
h () - zoom_box(3));
210 glVertex2d (zoom_box(2),
h () - zoom_box(1));
211 glVertex2d (zoom_box(0),
h () - zoom_box(1));
223 #if defined (HAVE_OPENGL)
225 glMatrixMode (GL_MODELVIEW);
229 glMatrixMode (GL_PROJECTION);
232 gluOrtho2D (0.0,
w (), 0.0,
h ());
234 glPushAttrib (GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT);
235 glDisable (GL_DEPTH_TEST);
237 glBegin (GL_POLYGON);
238 glColor4f (0.45, 0.62, 0.81, 0.1);
243 glBegin (GL_LINE_STRIP);
244 glColor4f (0.45, 0.62, 0.81, 0.9);
249 glMatrixMode (GL_MODELVIEW);
251 glMatrixMode (GL_PROJECTION);
262 int handle (
int event)
264 #if defined (HAVE_OPENGL)
269 cursor (FL_CURSOR_CROSS);
273 cursor (FL_CURSOR_DEFAULT);
277 return Fl_Gl_Window::handle (event);
288 void script_cb (Fl_Widget*,
void* data)
297 fltk_uimenu (
int xx,
int yy,
int ww,
int hh)
299 menubar =
new Fl_Menu_Bar (xx, yy, ww, hh);
302 int items_to_show (
void)
305 int len = menubar->size ();
307 for (
int t = 0;
t < len;
t++)
309 const Fl_Menu_Item *
m =
static_cast<const Fl_Menu_Item*
> (&
310 (menubar->menu ()[
t]));
311 if (m->label () && m->visible ())
330 bool is_visible (
void)
332 return menubar->visible ();
335 int find_index_by_name (
const std::string& findname)
344 for (
int t = 0;
t < menubar->size ();
t++)
346 Fl_Menu_Item *m =
const_cast<Fl_Menu_Item*
> (&(menubar->menu ()[
t]));
350 if (! menupath.empty ())
352 menupath += m->label ();
354 if (menupath == findname)
362 size_t idx = menupath.find_last_of (
"/");
363 if (idx != std::string::npos)
364 menupath.erase (idx);
371 if (! itempath.empty ())
373 itempath += m->label ();
375 if (itempath == findname)
385 Matrix retval = do_find_uimenu_children (uimenu_childs);
392 Matrix retval = do_find_uimenu_children (uimenu_childs);
396 Matrix do_find_uimenu_children (
Matrix uimenu_childs)
const
408 uimenu_childs(k) = uimenu_childs(ii);
415 uimenu_childs.
resize (k, 1);
422 retval(ii) = uimenu_childs (sidx(ii));
430 int idx = find_index_by_name (fltk_label.c_str ());
433 menubar->remove (idx);
439 if (! fltk_label.empty ())
441 Fl_Menu_Item* item =
const_cast<Fl_Menu_Item*
> (menubar->find_item (
442 fltk_label.c_str ()));
446 if (acc.length () > 0)
448 int key = FL_CTRL + acc[0];
449 item->shortcut (key);
458 if (! fltk_label.empty ())
460 Fl_Menu_Item* item =
const_cast<Fl_Menu_Item*
> (menubar->find_item (
461 fltk_label.c_str ()));
465 item->callback (static_cast<Fl_Callback*> (script_cb),
466 static_cast<void*> (&uimenup));
468 item->callback (0, static_cast<void*> (0));
476 if (! fltk_label.empty ())
478 Fl_Menu_Item* item =
const_cast<Fl_Menu_Item*
> (menubar->find_item (
479 fltk_label.c_str ()));
493 if (! fltk_label.empty ())
495 Fl_Menu_Item* item =
const_cast<Fl_Menu_Item*
> (menubar->find_item (
496 fltk_label.c_str ()));
501 uchar r =
static_cast<uchar
> (
std::floor (rgb (0) * 255));
502 uchar g =
static_cast<uchar
> (
std::floor (rgb (1) * 255));
503 uchar
b =
static_cast<uchar
> (
std::floor (rgb (2) * 255));
505 item->labelcolor (fl_rgb_color (r, g, b));
516 if (! fltk_label.empty ())
518 int itemflags = 0, idx;
519 int curr_idx = find_index_by_name (fltk_label.c_str ());
521 for (idx = curr_idx - 1; idx >= 0; idx--)
524 =
const_cast<Fl_Menu_Item*
> (&menubar->menu () [idx]);
525 itemflags = item->flags;
530 if (idx >= 0 && idx < menubar->
size ())
534 if (idx >= 0 && !(itemflags & FL_SUBMENU))
535 menubar->mode (idx, itemflags | FL_MENU_DIVIDER);
538 menubar->mode (idx, itemflags & (~FL_MENU_DIVIDER));
546 if (! fltk_label.empty ())
549 =
const_cast<Fl_Menu_Item*
> (menubar->find_item (fltk_label.c_str ()));
571 if (! fltk_label.empty ())
573 bool item_added =
false;
576 const Fl_Menu_Item* item
577 = menubar->find_item (fltk_label.c_str ());
582 size_t idx1 = fltk_label.find_last_of (
"(");
583 size_t idx2 = fltk_label.find_last_of (
")");
584 int len = idx2 - idx1;
588 std::string valstr = fltk_label.substr (idx1 + 1, len - 1);
589 fltk_label.erase (idx1, len + 1);
590 val = atoi (valstr.c_str ());
591 if (val > 0 && val < 99)
594 std::ostringstream valstream;
596 fltk_label +=
"(" + valstream.str () +
")";
600 Matrix uimenu_ch = find_uimenu_children (uimenup);
601 int len = uimenu_ch.
numel ();
606 flags += FL_MENU_TOGGLE + FL_MENU_VALUE;
607 menubar->add (fltk_label.c_str (), 0, 0, 0, flags);
611 while (! item_added);
618 std::vector<int> delayed_menus;
619 Matrix kids = find_uimenu_children (uimenup);
620 int len = kids.
numel ();
625 update_foregroundcolor (uimenup);
626 update_callback (uimenup);
627 update_accelerator (uimenup);
628 update_enable (uimenup);
629 update_visible (uimenup);
630 update_seperator (uimenup);
643 delayed_menus.push_back ((len - (ii + 1)));
652 for (
size_t ii = 0; ii < delayed_menus.size (); ii++)
661 update_position (kprop, ++count);
668 std::vector<int> delayed_menus;
669 Matrix kids = find_uimenu_children (figp);
670 int len = kids.
numel ();
685 delayed_menus.push_back ((len - (ii + 1)));
689 update_position (kprop, ++count);
695 for (
size_t ii = 0; ii < delayed_menus.size (); ii++)
704 update_position (kprop, ++count);
709 template <
typename T_prop>
710 void remove_from_menu (T_prop& prop)
714 kids = find_uimenu_children (prop);
715 int len = kids.
numel ();
725 remove_from_menu (kprop);
729 if (type ==
"uimenu")
730 delete_entry (dynamic_cast<uimenu::properties&> (prop));
731 else if (type ==
"figure")
744 fltk_uimenu (
const fltk_uimenu&);
746 fltk_uimenu operator = (
const fltk_uimenu&);
748 Fl_Menu_Bar* menubar;
751 #if defined (HAVE_X_WINDOWS)
753 xerror_handler (Display *, XErrorEvent *)
759 class plot_window :
public Fl_Window
761 friend class fltk_uimenu;
765 : Fl_Window (xx, yy, ww, hh + menu_h + status_h + 2,
"octave"),
766 window_label (), fp (xfp), canvas (0),
767 autoscale (0), togglegrid (0), panzoom (0), rotate (0), help (0),
768 status (0), resize_dummy (0), ax_obj (), pos_x (0), pos_y (0)
770 callback (window_close, static_cast<void*> (
this));
773 resize_dummy =
new Fl_Box (5 * status_h, menu_h,
774 ww - 5 * status_h, hh);
777 resizable (resize_dummy);
787 uimenu =
new fltk_uimenu (0, 0, ww, menu_h);
788 canvas =
new OpenGL_fltk (0, menu_h, ww, hh, number ());
794 int toolbar_y = menu_h + hh + 1;
795 status =
new Fl_Output (5 * status_h, toolbar_y,
796 ww - 5 * status_h, status_h,
"");
798 status->textcolor (FL_BLACK);
799 status->color (FL_GRAY);
800 status->textfont (FL_COURIER);
801 status->textsize (10);
802 status->box (FL_ENGRAVED_BOX);
804 autoscale =
new Fl_Button (0, toolbar_y, status_h, status_h,
"A");
805 autoscale->callback (button_callback, static_cast<void*> (
this));
806 autoscale->tooltip (
"Autoscale");
808 togglegrid =
new Fl_Button (status_h, toolbar_y, status_h, status_h,
"G");
809 togglegrid->callback (button_callback, static_cast<void*> (
this));
810 togglegrid->tooltip (
"Toggle Grid");
812 panzoom =
new Fl_Button (2* status_h, toolbar_y, status_h, status_h,
"P");
813 panzoom->callback (button_callback, static_cast<void*> (
this));
814 panzoom->tooltip (
"Mouse Pan/Zoom");
816 rotate =
new Fl_Button (3 * status_h, toolbar_y, status_h, status_h,
"R");
817 rotate->callback (button_callback, static_cast<void*> (
this));
818 rotate->tooltip (
"Mouse Rotate");
820 help =
new Fl_Button (4 * status_h, toolbar_y, status_h, status_h,
"?");
821 help->callback (button_callback, static_cast<void*> (
this));
822 help->tooltip (
"Help");
828 if (fp.menubar_is (
"none") || !
uimenu->items_to_show ())
831 update_boundingbox (
internal);
833 if (fp.is_visible ())
845 #if defined (HAVE_X_WINDOWS)
850 if (show_gui_msgs.empty ())
851 XSetErrorHandler (xerror_handler);
854 if (fp.get_currentaxes ().ok ())
867 double number (
void) {
return fp.get___myhandle__ ().value (); }
869 void renumber (
double new_number)
872 error (
"unable to renumber figure");
874 if (canvas->renumber (new_number))
880 canvas->print (cmd, term);
883 void show_menubar (
void)
886 update_toolbar_position ();
889 void hide_menubar (
void)
892 update_toolbar_position ();
911 uimenu->remove_from_menu (uimenup);
915 uimenu->update_visible (uimenup);
919 uimenu->update_accelerator (uimenup);
923 uimenu->update_callback (uimenup);
927 uimenu->add_to_menu (figp);
931 uimenu->update_enable (uimenup);
935 uimenu->update_foregroundcolor (uimenup);
939 uimenu->add_to_menu (figp);
943 uimenu->add_to_menu (figp);
947 uimenu->update_seperator (uimenup);
951 if (
uimenu->items_to_show ())
958 void show_canvas (
void)
960 if (! canvas->can_do ())
961 error (
"unable to plot due to insufficient OpenGL support");
962 else if (fp.is_visible ())
965 canvas->make_current ();
969 void hide_canvas (
void)
978 void update_toolbar_position ()
980 int old_canvas_h = canvas->h ();
983 update_boundingbox (
true);
984 canvas->resize (0, menu_dy (),
w (), old_canvas_h);
986 int toolbar_y = canvas->h () + menu_dy () + 1;
987 autoscale->position (0, toolbar_y);
988 togglegrid->position (status_h, toolbar_y);
989 panzoom->position (2 * status_h, toolbar_y);
990 rotate->position (3 * status_h, toolbar_y);
991 help->position (4 * status_h, toolbar_y);
992 status->resize (5 * status_h, toolbar_y,
993 w () - 5 * status_h, status_h);
1001 pos(1) += menu_dy ();
1002 pos(3) -= menu_dy () + status_h + 2;
1009 outerpos(1) -= menu_dy ();
1010 outerpos(3) += menu_dy () + status_h + 2;
1019 void update_boundingbox (
bool internal)
1021 Matrix bb = fp.get_boundingbox (
internal);
1023 bb = position2outerposition (bb);
1024 resize (bb(0), bb(1), bb(2), bb(3));
1027 void mark_modified (
void)
1032 void set_name (
void)
1034 window_label = fp.get_title ();
1035 label (window_label.c_str ());
1042 plot_window (
const plot_window&);
1044 plot_window& operator = (
const plot_window&);
1054 static const int status_h = 20;
1057 static const int menu_h = 25;
1060 static void window_close (Fl_Widget*,
void* data)
1063 args(0) =
static_cast<plot_window*
> (data)->number ();
1064 feval (
"close", args);
1068 static void button_callback (Fl_Widget* ww,
void* data)
1070 static_cast<plot_window*
> (data)->button_press (ww, data);
1073 void button_press (Fl_Widget* widg,
void*)
1075 if (widg == autoscale)
1077 else if (widg == togglegrid)
1079 else if (widg == panzoom)
1081 else if (widg == rotate)
1083 else if (widg == help)
1084 fl_message (
"%s", help_text);
1090 if (ax_obj && ax_obj.isa (
"axes")
1091 && ax_obj.get_properties ().get_tag () !=
"legend"
1092 && ax_obj.get_properties ().get_tag () !=
"colorbar")
1096 ap.
set (name, value);
1106 ap.
set (name, value);
1112 OpenGL_fltk* canvas;
1113 Fl_Button* autoscale;
1114 Fl_Button* togglegrid;
1119 Fl_Box* resize_dummy;
1124 void axis_auto (
void)
1131 feval (
"axis", args);
1136 void toggle_grid (
void)
1142 feval (
"grid", args);
1146 void pixel2pos (
const graphics_handle& ax,
int px,
int py,
double& xx,
1155 if (ax && ax.
isa (
"axes"))
1168 int len = kids.
numel ();
1170 for (
int k = 0; k < len; k++)
1182 if (bb(0) <= px && px < (bb(0)+bb(2))
1183 && bb(1) <= py && py < (bb(1)+bb(3)))
1194 int px1 = -1,
int py1 = -1)
1200 int px1 = -1,
int py1 = -1)
1202 double x0, y0, x1, y1;
1204 std::stringstream cbuf;
1207 pixel2pos (ax, px0, py0, x0, y0);
1208 cbuf <<
"[" << x0 <<
", " << y0 <<
"]";
1211 pixel2pos (ax, px1, py1, x1, y1);
1212 cbuf <<
" -> ["<< x1 <<
", " << y1 <<
"]";
1215 status->value (cbuf.str ().c_str ());
1220 if (ax && ax.
isa (
"axes"))
1224 std::stringstream cbuf;
1229 cbuf <<
"[azimuth: " << v(0) <<
", elevation: " << v(1) <<
"]";
1231 status->value (cbuf.str ().c_str ());
1235 void set_currentpoint (
int px,
int py)
1278 if (uimenu->is_visible ())
1292 std::ostringstream tmp_str;
1294 if (e_key == FL_Escape)
1296 else if (e_key == FL_Tab)
1298 else if (e_key == FL_Caps_Lock)
1299 key_str =
"capslock";
1300 else if (e_key == FL_Shift_L || e_key == FL_Shift_R)
1302 else if (e_key == FL_Control_L || e_key == FL_Control_R)
1303 key_str =
"control";
1304 else if (e_key == FL_Meta_L || e_key == FL_Meta_R)
1305 key_str =
"windows";
1306 else if (e_key == FL_Alt_L || e_key == FL_Alt_R)
1308 else if (e_key == 32)
1310 else if (e_key == FL_Enter)
1312 else if (e_key == FL_BackSpace)
1313 key_str =
"backspace";
1314 else if (e_key == FL_Print)
1315 key_str =
"printscreen";
1316 else if (e_key == FL_Pause)
1318 else if (e_key == FL_Home)
1320 else if (e_key == FL_End)
1322 else if (e_key == FL_Insert)
1324 else if (e_key == FL_Page_Up)
1326 else if (e_key == FL_Delete)
1328 else if (e_key == FL_Page_Down)
1329 key_str =
"pagedown";
1330 else if (e_key == FL_Left)
1331 key_str =
"leftarrow";
1332 else if (e_key == FL_Up)
1333 key_str =
"uparrow";
1334 else if (e_key == FL_Right)
1335 key_str =
"rightarrow";
1336 else if (e_key == FL_Down)
1337 key_str =
"downarrow";
1338 else if (e_key == FL_Num_Lock)
1339 key_str =
"numlock";
1340 else if (e_key == 0xffaf)
1342 else if (e_key == 0xffaa)
1343 key_str =
"multiply";
1344 else if (e_key == 0xffad)
1345 key_str =
"subtract";
1346 else if (e_key == 0xffab)
1348 else if (e_key == 0xff8d)
1350 else if (e_key == 0xffac)
1351 key_str =
"separator";
1352 else if (e_key >= 0xffb0 && e_key <= 0xffb9)
1354 tmp_str <<
"numpad" << (e_key - 0xffb0);
1355 key_str = tmp_str.str ();
1357 else if (e_key >= (FL_F + 1) && e_key <= (FL_F + 12))
1359 tmp_str <<
"f" << (e_key - FL_F);
1360 key_str = tmp_str.str ();
1362 else if (e_key ==
',')
1364 else if (e_key ==
'.')
1366 else if (e_key ==
'-')
1368 else if (e_key ==
'^' || e_key ==
'+' || e_key ==
'#'
1369 || e_key ==
'<' || e_key == 0xfe03 )
1371 else if (isalnum (e_key))
1372 key_str = std::tolower (e_key);
1373 else if (isprint (e_text[0]))
1380 Cell modifier2cell (
int e_state)
1384 if (e_state & FL_SHIFT)
1386 if (e_state & FL_CTRL)
1388 if (e_state & FL_ALT)
1390 if (e_state & FL_COMMAND)
1395 void resize (
int xx,
int yy,
int ww,
int hh)
1397 Fl_Window::resize (xx, yy, ww, hh);
1432 bool rotate_enabled (
void)
1442 int handle (
int event)
1444 if (event == FL_FOCUS)
1456 static bool key_resent_detected =
false;
1463 static int last_event_key = 0;
1464 static char last_event_text = 0;
1466 int e_key = Fl::event_key ();
1467 char e_text = Fl::event_text ()[0];
1468 key_resent_detected = (e_key == last_event_key
1469 && std::tolower (last_event_text) == std::tolower (e_text)
1470 && ((islower (last_event_text) && isupper (e_text))
1471 || (isupper (last_event_text) && islower (e_text))));
1473 last_event_key = e_key;
1474 last_event_text = e_text;
1480 int e_key = Fl::event_key ();
1481 const char *e_text = Fl::event_text ();
1482 int e_state = Fl::event_state ();
1491 if (Fl::event_inside (canvas))
1493 pos_x = Fl::event_x ();
1494 pos_y = Fl::event_y () - menu_dy ();
1496 set_currentpoint (pos_x, pos_y);
1498 gh = pixel2axes_or_ca (pos_x, pos_y);
1503 set_axes_currentpoint (ax_obj, pos_x, pos_y);
1538 int e_key = Fl::event_key ();
1539 int e_state = Fl::event_state ();
1541 if (key_resent_detected && Fl::event_length () == 1)
1546 tmp_e_text[0] = Fl::event_text ()[0];
1549 if (std::islower (tmp_e_text[0]))
1550 tmp_e_text[0] = std::toupper (tmp_e_text[0]);
1552 tmp_e_text[0] = std::tolower (tmp_e_text[0]);
1553 evt = format_key_event (e_key, tmp_e_text, e_state);
1557 const char *e_text = Fl::event_text ();
1558 evt = format_key_event (e_key, e_text, e_state);
1570 if (Fl::event_inside (canvas))
1574 pixel2status (pixel2axes_or_ca (Fl::event_x (),
1575 Fl::event_y () - menu_dy ()),
1576 Fl::event_x (), Fl::event_y () - menu_dy ());
1580 pos_x = Fl::event_x ();
1581 pos_y = Fl::event_y () - menu_dy ();
1583 set_currentpoint (pos_x, pos_y);
1585 if (Fl::event_clicks ())
1587 else if (Fl::event_button () == FL_MIDDLE_MOUSE
1588 || (Fl::event_button () == FL_LEFT_MOUSE
1589 && Fl::event_shift ()))
1591 else if (Fl::event_button () == FL_RIGHT_MOUSE
1592 || (Fl::event_button () == FL_LEFT_MOUSE
1593 && Fl::event_ctrl ()))
1598 gh = pixel2axes_or_ca (pos_x, pos_y);
1603 set_axes_currentpoint (ax_obj, pos_x, pos_y);
1616 rotate->activate ();
1618 rotate->deactivate ();
1636 set_currentpoint (Fl::event_x (), Fl::event_y () - menu_dy ());
1640 if (Fl::event_button () == 1)
1642 if (ax_obj && ax_obj.
isa (
"axes"))
1649 if (ap.
get_tag () !=
"legend")
1651 if (rotate_enabled ())
1652 view2status (ax_obj);
1654 pixel2status (ax_obj, pos_x, pos_y,
1656 Fl::event_y () - menu_dy ());
1658 double x0, y0, x1, y1;
1660 pixel2pos (ax_obj, pos_x, pos_y, x0, y0);
1661 pixel2pos (ax_obj, Fl::event_x (),
1662 Fl::event_y () - menu_dy (),
1671 else if (rotate_enabled ())
1674 daz = (Fl::event_x () - pos_x) / pos(2) * 360;
1675 del = (Fl::event_y () - menu_dy () - pos_y)
1684 pos(0) +=
double (Fl::event_x () - pos_x)
1686 pos(1) -=
double (Fl::event_y () - menu_dy () - pos_y)
1691 pos_x = Fl::event_x ();
1692 pos_y = Fl::event_y () - menu_dy ();
1697 else if (Fl::event_button () == 3)
1699 pixel2status (ax_obj, pos_x, pos_y,
1700 Fl::event_x (), Fl::event_y () - menu_dy ());
1702 zoom_box (0) = pos_x;
1703 zoom_box (1) = pos_y;
1704 zoom_box (2) = Fl::event_x ();
1705 zoom_box (3) = Fl::event_y () - menu_dy ();
1706 canvas->set_zoom_box (zoom_box);
1707 canvas->zoom (
true);
1720 if (ax && ax.
isa (
"axes"))
1729 const double factor = (Fl::event_dy () < 0
1730 ? 1 / (1.0 - wheel_zoom_speed)
1731 : 1.0 - wheel_zoom_speed);
1735 pixel2pos (ax, Fl::event_x (), Fl::event_y () - menu_dy (),
1749 set_currentpoint (Fl::event_x (), Fl::event_y () - menu_dy ());
1753 if ((Fl::event_button () == 1) && Fl::event_clicks ())
1756 set_on_ax_obj (
"xlimmode",
"auto");
1757 set_on_ax_obj (
"ylimmode",
"auto");
1758 set_on_ax_obj (
"zlimmode",
"auto");
1762 if (Fl::event_button () == 3)
1765 if (canvas->zoom ())
1767 canvas->zoom (
false);
1769 if (ax_obj && ax_obj.
isa (
"axes"))
1773 pixel2pos (ax_obj, pos_x, pos_y, x0, y0);
1774 int pos_x1 = Fl::event_x ();
1775 int pos_y1 = Fl::event_y () - menu_dy ();
1776 pixel2pos (ax_obj, pos_x1, pos_y1, x1, y1);
1779 int dx =
abs (pos_x - pos_x1);
1780 int dy =
abs (pos_y - pos_y1);
1782 if ((dx > 4) && (dy > 4))
1804 ap.
zoom (
"both", xl, yl);
1815 return Fl_Window::handle (event);
1819 class figure_manager
1823 static bool instance_ok (
void)
1828 instance =
new figure_manager ();
1831 error (
"unable to create figure_manager object!");
1836 ~figure_manager (
void)
1841 static void close_all (
void)
1844 instance->do_close_all ();
1850 instance->do_new_window (fp);
1853 static void delete_window (
int idx)
1856 instance->do_delete_window (idx);
1859 static void delete_window (
const std::string& idx_str)
1861 delete_window (str2idx (idx_str));
1864 static void renumber_figure (
const std::string& idx_str,
double new_number)
1867 instance->do_renumber_figure (str2idx (idx_str), new_number);
1870 static void toggle_window_visibility (
int idx,
bool is_visible)
1873 instance->do_toggle_window_visibility (idx, is_visible);
1876 static void toggle_window_visibility (
const std::string& idx_str,
1879 toggle_window_visibility (str2idx (idx_str), is_visible);
1882 static void mark_modified (
int idx)
1885 instance->do_mark_modified (idx);
1890 mark_modified (hnd2idx (gh));
1893 static void set_name (
int idx)
1896 instance->do_set_name (idx);
1901 set_name (str2idx (idx_str));
1906 return instance_ok () ? instance->do_get_size (idx) :
Matrix ();
1918 instance->do_print (hnd2idx (gh), cmd, term);
1925 instance->do_uimenu_update (hnd2idx (figh), uimenuh,
id);
1932 instance->do_update_canvas (hnd2idx (gh), ca);
1935 static void update_boundingbox (
const std::string& fig_idx_str,
1939 instance->do_update_boundingbox (str2idx (fig_idx_str),
internal);
1942 static void toggle_menubar_visibility (
const std::string& fig_idx_str,
1943 bool menubar_is_figure)
1946 instance->do_toggle_menubar_visibility (str2idx (fig_idx_str),
1952 static figure_manager *instance;
1954 figure_manager (
void) { }
1957 figure_manager (
const figure_manager&);
1958 figure_manager& operator = (
const figure_manager&);
1962 static int curr_index;
1963 typedef std::map<int, plot_window*> window_map;
1964 typedef window_map::iterator wm_iterator;;
1969 void do_close_all (
void)
1972 for (win = windows.begin (); win != windows.end (); win++)
1979 int idx = figprops2idx (fp);
1981 if (idx >= 0 && windows.find (idx) == windows.end ())
1984 bool internal =
false;
1986 if (pos(2) != -1.0 && pos(3) != -1.0)
1997 idx2figprops (curr_index, fp);
1999 windows[curr_index++] =
new plot_window (pos(0), pos(1), pos(2), pos(3),
2004 void do_delete_window (
int idx)
2006 wm_iterator win = windows.find (idx);
2008 if (win != windows.end ())
2011 windows.erase (win);
2015 void do_renumber_figure (
int idx,
double new_number)
2017 wm_iterator win = windows.find (idx);
2019 if (win != windows.end ())
2020 win->second->renumber (new_number);
2023 void do_toggle_window_visibility (
int idx,
bool is_visible)
2025 wm_iterator win = windows.find (idx);
2027 if (win != windows.end ())
2031 win->second->show ();
2032 win->second->show_canvas ();
2035 win->second->hide ();
2040 void do_toggle_menubar_visibility (
int fig_idx,
bool menubar_is_figure)
2042 wm_iterator win = windows.find (fig_idx);
2044 if (win != windows.end ())
2046 if (menubar_is_figure)
2047 win->second->show_menubar ();
2049 win->second->hide_menubar ();
2051 win->second->redraw ();
2055 void do_mark_modified (
int idx)
2057 wm_iterator win = windows.find (idx);
2059 if (win != windows.end ())
2061 win->second->mark_modified ();
2065 void do_set_name (
int idx)
2067 wm_iterator win = windows.find (idx);
2069 if (win != windows.end ())
2070 win->second->set_name ();
2073 Matrix do_get_size (
int idx)
2077 wm_iterator win = windows.find (idx);
2079 if (win != windows.end ())
2081 sz(0) = win->second->w ();
2082 sz(1) = win->second->h ();
2090 wm_iterator win = windows.find (idx);
2092 if (win != windows.end ())
2093 win->second->print (cmd, term);
2098 wm_iterator win = windows.find (idx);
2100 if (win != windows.end ())
2101 win->second->uimenu_update (gh,
id);
2106 wm_iterator win = windows.find (idx);
2108 if (win != windows.end ())
2111 win->second->show_canvas ();
2113 win->second->hide_canvas ();
2117 void do_update_boundingbox (
int idx,
bool internal)
2119 wm_iterator win = windows.find (idx);
2121 if (win != windows.end ())
2122 win->second->update_boundingbox (
internal);
2128 if (clstr.find (fltk_idx_header,0) == 0)
2130 std::istringstream istr (clstr.substr (fltk_idx_header.size ()));
2135 error (
"figure_manager: could not recognize fltk index");
2140 std::ostringstream ind_str;
2141 ind_str << fltk_idx_header << idx;
2156 error (
"figure_manager: figure is not fltk");
2159 static int hnd2idx (
double h)
2162 if (fobj && fobj.
isa (
"figure"))
2166 return figprops2idx (fp);
2169 error (
"figure_manager: H (= %g) is not a figure", h);
2174 return hnd2idx (fh.
value ());
2178 figure_manager *figure_manager::instance = 0;
2180 std::string figure_manager::fltk_idx_header=
"fltk index=";
2181 int figure_manager::curr_index = 1;
2188 fltk_graphics_toolkit (
void)
2190 input_event_hook_fcn_id ()
2192 Fl::visual (FL_RGB);
2195 ~fltk_graphics_toolkit (
void) { }
2197 bool is_valid (
void)
const {
return true; }
2201 if (go.
isa (
"figure")
2202 || go.
isa (
"uimenu"))
2204 if (go.
isa (
"uimenu"))
2215 if (go.
isa (
"figure"))
2232 if (go.
isa (
"uimenu"))
2233 fltk_label = dynamic_cast<const uimenu::properties&>
2237 else if (go.
isa (
"figure") || go.
isa (
"uicontextmenu"))
2240 error (
"invalid parent object\n");
2248 if (go.
isa (
"figure"))
2260 figure_manager::toggle_window_visibility (ov.
string_value (),
2265 figure_manager::toggle_menubar_visibility
2270 figure_manager::update_canvas (go.
get_handle (),
2283 figure_manager::renumber_figure (tmp, gh.
value ());
2284 figure_manager::set_name (tmp);
2289 figure_manager::update_boundingbox (ov.
string_value (),
true);
2293 figure_manager::update_boundingbox (ov.
string_value (),
false);
2298 else if (go.
isa (
"uimenu"))
2301 uimenu_set_fltk_label (go);
2312 if (obj && obj.
isa (
"root"))
2320 if (fobj && fobj.
isa (
"figure"))
2325 == FLTK_GRAPHICS_TOOLKIT_NAME)
2326 figure_manager::new_window (fp);
2331 figure_manager::mark_modified (go.
get_handle ());
2340 figure_manager::print (go.
get_handle (), file_cmd, term);
2378 figure_manager::close_all ();
2384 input_event_hook_fcn_id =
id;
2399 #if defined (HAVE_FLTK)
2419 #if defined (HAVE_FLTK)
2421 error (
"__init_fltk__: no graphics DISPLAY available");
2422 else if (! toolkit_loaded)
2426 fltk_graphics_toolkit *fltk =
new fltk_graphics_toolkit ();
2429 toolkit_loaded =
true;
2435 fltk->set_input_event_hook_id (
id);
graphics_handle get_parent(void) const
octave_value get_position(void) const
bool is_visible(void) const
void resize(octave_idx_type nr, octave_idx_type nc, double rfv=0)
Array< octave_idx_type > sort_rows_idx(sortmode mode=ASCENDING) const
Sort by rows returns only indices.
bool isa(const std::string &go_name) const
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).is_integer_type())
octave_value get_buttondownfcn(void) const
octave_idx_type numel(void) const
Number of elements in the array.
identity matrix If supplied two scalar respectively For allows like xample val
const octave_value & contents(const_iterator p) const
Return the CPU time used by your Octave session The first output is the total time spent executing your process and is equal to the sum of second and third which are the number of CPU seconds spent executing in user mode and the number of CPU seconds spent executing in system mode
octave_value_list & append(const octave_value &val)
virtual void draw(const graphics_object &go, bool toplevel=true)
octave_int< T > mod(const octave_int< T > &x, const octave_int< T > &y)
OCTINTERP_API octave_value_list Fdrawnow(const octave_value_list &=octave_value_list(), int=0)
void error(const char *fmt,...)
void zoom(const std::string &mode, double factor, bool push_to_zoom_stack=true)
virtual Matrix get_boundingbox(bool=false, const Matrix &=Matrix()) const
void translate_view(const std::string &mode, double x0, double x1, double y0, double y1, bool push_to_zoom_stack=true)
OCTINTERP_API octave_value_list Fremove_input_event_hook(const octave_value_list &=octave_value_list(), int=0)
static void load_toolkit(const graphics_toolkit &tk)
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function t
OCTINTERP_API octave_value_list Fadd_input_event_hook(const octave_value_list &=octave_value_list(), int=0)
std::string get_tag(void) const
OCTAVE_EXPORT octave_value_list F__fltk_check__(const octave_value_list &, int)
octave_value get(bool all=false) const
static std::string getenv(const std::string &name)
graphics_xform get_transform(void) const
void set_currentpoint(const octave_value &val)
Matrix get_children(void) const
bool is_beingdeleted(void) const
std::string string_value(bool force=false) const
nd deftypefn *octave_map m
bool set(const octave_value &val, bool do_run=true, bool do_notify_toolkit=true)
double get_mousewheelzoom(void) const
std::complex< double > w(std::complex< double > z, double relerr=0)
static bool toolkit_loaded
void gl2ps_print(const graphics_object &fig, const std::string &stream, const std::string &term)
bool is_string(void) const
void rotate_view(double delta_az, double delta_el, bool push_to_zoom_stack=true)
string_vector & append(const std::string &s)
#define panic_impossible()
octave_value get(bool all=false) const
base_properties & get_properties(void)
void set_position(const octave_value &val)
OCTINTERP_API void munlock(const std::string &)
octave_idx_type length(void) const
void zoom_about_point(const std::string &mode, double x, double y, double factor, bool push_to_zoom_stack=true)
graphics_object get_ancestor(const std::string &type) const
Matrix matrix_value(bool frc_str_conv=false) const
void set(const caseless_str &pname, const octave_value &val)
void execute_buttondownfcn(const octave_value &data=octave_value()) const
bool valid_object(void) const
bool is_empty(void) const
ColumnVector pixel2coord(double px, double py) const
octave_scalar_map scalar_map_value(void) const
OCTAVE_EXPORT octave_value_list return the value of the option it must match the dimension of the state and the relative tolerance must also be a vector of the same length tem it must match the dimension of the state and the absolute tolerance must also be a vector of the same length The local error test applied at each integration step is xample roup abs(local error in x(i))<
static octave_idx_type get_size(double d, const std::string &who)
void assign(const std::string &k, const octave_value &val)
OCTAVE_EXPORT octave_value_list or N dimensional array whose elements are all equal to the IEEE symbol zero divided by nd tex zero divided by nd ifnottex and any operation involving another NaN value(5+NaN).Note that NaN always compares not equal to NaN(NaN!
static bool display_available(void)
static graphics_handle lookup(double val)
static bool pan_enabled(const graphics_object figObj)
issues an error eealso double
Matrix get_all_children(void) const
OCTAVE_EXPORT octave_value_list or N dimensional array whose elements are all equal to the IEEE symbol NaN(Not a Number).NaN is the result of operations which do not produce a well defined 0 result.Common operations which produce a NaN are arithmetic with infinity ex($\infty-\infty $)
static graphics_object get_object(double val)
graphics_handle get_parent(void) const
OCTINTERP_API int calc_dimensions(const graphics_object &gh)
static std::string pan_mode(const graphics_object figObj)
#define DEFUN_DLD(name, args_name, nargout_name, doc)
graphics_handle get_handle(void) const
graphics_handle get___myhandle__(void) const
Matrix get_transform_zlim(void) const
octave_value as_octave_value(void) const
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
OCTINTERP_API void mlock(void)