47 #if defined (HAVE_X_WINDOWS)
57 #define WIN32_LEAN_AND_MEAN
61 #include <FL/Fl_Box.H>
62 #include <FL/Fl_Button.H>
63 #include <FL/Fl_Choice.H>
64 #include <FL/Fl_File_Chooser.H>
65 #include <FL/Fl_Gl_Window.H>
67 #include <FL/Fl_Menu_Bar.H>
68 #include <FL/Fl_Menu_Button.H>
69 #include <FL/Fl_Output.H>
70 #include <FL/Fl_Window.H>
71 #include <FL/fl_ask.H>
72 #include <FL/fl_draw.H>
94 #define FLTK_GRAPHICS_TOOLKIT_NAME "fltk"
96 const char* help_text =
"\
105 mouse wheel - zoom\n\
106 right drag - rectangle zoom\n\
107 left double click - autoscale\n\
110 class OpenGL_fltk :
public Fl_Gl_Window
113 OpenGL_fltk (
int xx,
int yy,
int ww,
int hh,
double num)
114 : Fl_Gl_Window (xx, yy, ww, hh, 0), number (num), renderer (),
115 in_zoom (false), zoom_box ()
118 mode (FL_DEPTH | FL_DOUBLE | FL_MULTISAMPLE);
121 ~OpenGL_fltk (
void) { }
130 bool zoom (
void) {
return in_zoom; }
131 void set_zoom_box (
const Matrix& zb) { zoom_box = zb; }
133 void print (
const std::string& cmd,
const std::string& term)
140 void resize (
int xx,
int yy,
int ww,
int hh)
142 Fl_Gl_Window::resize (xx, yy, ww, hh);
145 bool renumber (
double new_number)
149 if (number != new_number)
169 glMatrixMode (GL_PROJECTION);
171 glViewport (0, 0,
w (), h ());
180 void zoom_box_vertex (
void)
182 glVertex2d (zoom_box(0), h () - zoom_box(1));
183 glVertex2d (zoom_box(0), h () - zoom_box(3));
184 glVertex2d (zoom_box(2), h () - zoom_box(3));
185 glVertex2d (zoom_box(2), h () - zoom_box(1));
186 glVertex2d (zoom_box(0), h () - zoom_box(1));
193 glMatrixMode (GL_MODELVIEW);
196 glMatrixMode (GL_PROJECTION);
198 gluOrtho2D (0.0,
w (), 0.0, h ());
200 glPushAttrib (GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT);
201 glDisable (GL_DEPTH_TEST);
203 glBegin (GL_POLYGON);
204 glColor4f (0.45, 0.62, 0.81, 0.1);
208 glBegin (GL_LINE_STRIP);
210 glColor4f (0.45, 0.62, 0.81, 0.9);
218 int handle (
int event)
223 cursor (FL_CURSOR_CROSS);
227 cursor (FL_CURSOR_DEFAULT);
230 return Fl_Gl_Window::handle (event);
234 void script_cb (Fl_Widget*,
void* data)
243 fltk_uimenu (
int xx,
int yy,
int ww,
int hh)
245 menubar =
new Fl_Menu_Bar (xx, yy, ww, hh);
248 int items_to_show (
void)
251 int len = menubar->size ();
253 for (
int t = 0; t < len; t++)
255 const Fl_Menu_Item *m =
static_cast<const Fl_Menu_Item*
> (&
256 (menubar->menu ()[t]));
257 if (m->label () && m->visible ())
276 bool is_visible (
void)
278 return menubar->visible ();
281 int find_index_by_name (
const std::string& findname)
289 std::string menupath;
290 for (
int t = 0; t < menubar->size (); t++)
292 Fl_Menu_Item *m =
const_cast<Fl_Menu_Item*
> (&(menubar->menu ()[t]));
296 if (!menupath.empty ())
298 menupath += m->label ();
300 if (menupath.compare (findname) == 0)
308 size_t idx = menupath.find_last_of (
"/");
309 if (idx != std::string::npos)
310 menupath.erase (idx);
316 std::string itempath = menupath;
317 if (!itempath.empty ())
319 itempath += m->label ();
321 if (itempath.compare (findname) == 0)
331 Matrix retval = do_find_uimenu_children (uimenu_childs);
338 Matrix retval = do_find_uimenu_children (uimenu_childs);
342 Matrix do_find_uimenu_children (
Matrix uimenu_childs)
const
355 uimenu_childs(k) = uimenu_childs(ii);
362 uimenu_childs.
resize (k, 1);
369 retval(ii) = uimenu_childs (sidx(ii));
377 int idx = find_index_by_name (fltk_label.c_str ());
380 menubar->remove (idx);
386 if (!fltk_label.empty ())
388 Fl_Menu_Item* item =
const_cast<Fl_Menu_Item*
> (menubar->find_item (
389 fltk_label.c_str ()));
393 if (acc.length () > 0)
395 int key = FL_CTRL + acc[0];
396 item->shortcut (key);
405 if (!fltk_label.empty ())
407 Fl_Menu_Item* item =
const_cast<Fl_Menu_Item*
> (menubar->find_item (
408 fltk_label.c_str ()));
412 item->callback (static_cast<Fl_Callback*> (script_cb),
413 static_cast<void*> (&uimenup));
415 item->callback (0, static_cast<void*> (0));
423 if (!fltk_label.empty ())
425 Fl_Menu_Item* item =
const_cast<Fl_Menu_Item*
> (menubar->find_item (
426 fltk_label.c_str ()));
440 if (!fltk_label.empty ())
442 Fl_Menu_Item* item =
const_cast<Fl_Menu_Item*
> (menubar->find_item (
443 fltk_label.c_str ()));
448 uchar r =
static_cast<uchar
> (
gnulib::floor (rgb (0) * 255));
449 uchar g =
static_cast<uchar
> (
gnulib::floor (rgb (1) * 255));
450 uchar b =
static_cast<uchar
> (
gnulib::floor (rgb (2) * 255));
452 item->labelcolor (fl_rgb_color (r, g, b));
463 if (!fltk_label.empty ())
465 int itemflags = 0, idx;
466 int curr_idx = find_index_by_name (fltk_label.c_str ());
468 for (idx = curr_idx - 1; idx >= 0; idx--)
471 =
const_cast<Fl_Menu_Item*
> (&menubar->menu () [idx]);
472 itemflags = item->flags;
477 if (idx >= 0 && idx < menubar->
size ())
481 if (idx >= 0 && !(itemflags & FL_SUBMENU))
482 menubar->mode (idx, itemflags | FL_MENU_DIVIDER);
485 menubar->mode (idx, itemflags & (~FL_MENU_DIVIDER));
493 if (!fltk_label.empty ())
496 =
const_cast<Fl_Menu_Item*
> (menubar->find_item (fltk_label.c_str ()));
517 if (!fltk_label.empty ())
519 bool item_added =
false;
522 const Fl_Menu_Item* item
523 = menubar->find_item (fltk_label.c_str ());
528 size_t idx1 = fltk_label.find_last_of (
"(");
529 size_t idx2 = fltk_label.find_last_of (
")");
530 int len = idx2 - idx1;
534 std::string valstr = fltk_label.substr (idx1 + 1, len - 1);
535 fltk_label.erase (idx1, len + 1);
536 val = atoi (valstr.c_str ());
537 if (val > 0 && val < 99)
540 std::ostringstream valstream;
542 fltk_label +=
"(" + valstream.str () +
")";
546 Matrix uimenu_ch = find_uimenu_children (uimenup);
547 int len = uimenu_ch.
numel ();
552 flags += FL_MENU_TOGGLE + FL_MENU_VALUE;
553 menubar->add (fltk_label.c_str (), 0, 0, 0, flags);
564 std::vector<int> delayed_menus;
565 Matrix kids = find_uimenu_children (uimenup);
571 update_foregroundcolor (uimenup);
572 update_callback (uimenup);
573 update_accelerator (uimenup);
574 update_enable (uimenup);
575 update_visible (uimenup);
576 update_seperator (uimenup);
589 delayed_menus.push_back ((len - (ii + 1)));
598 for (
size_t ii = 0; ii < delayed_menus.size (); ii++)
607 update_position (kprop, ++count);
614 std::vector<int> delayed_menus;
615 Matrix kids = find_uimenu_children (figp);
631 delayed_menus.push_back ((len - (ii + 1)));
635 update_position (kprop, ++count);
641 for (
size_t ii = 0; ii < delayed_menus.size (); ii++)
650 update_position (kprop, ++count);
655 template <
class T_prop>
656 void remove_from_menu (T_prop& prop)
659 std::string
type = prop.get_type ();
660 kids = find_uimenu_children (prop);
671 remove_from_menu (kprop);
675 if (type.compare (
"uimenu") == 0)
676 delete_entry (dynamic_cast<uimenu::properties&> (prop));
677 else if (type.compare (
"figure") == 0)
690 fltk_uimenu (
const fltk_uimenu&);
692 fltk_uimenu operator = (
const fltk_uimenu&);
694 Fl_Menu_Bar* menubar;
697 #if defined (HAVE_X_WINDOWS)
699 xerror_handler (Display *, XErrorEvent *)
705 class plot_window :
public Fl_Window
707 friend class fltk_uimenu;
711 : Fl_Window (xx, yy, ww, hh + menu_h + status_h + 2,
"octave"),
712 window_label (), fp (xfp), canvas (0),
713 autoscale (0), togglegrid (0), panzoom (0), rotate (0), help (0),
714 status (0), resize_dummy (0), ax_obj (), pos_x (0), pos_y (0)
716 callback (window_close, static_cast<void*> (
this));
719 resize_dummy =
new Fl_Box (5 * status_h + 1, menu_h + 1,
720 ww - 5 * status_h - 1, hh);
723 resizable (resize_dummy);
733 uimenu =
new fltk_uimenu (0, 0, ww, menu_h);
734 canvas =
new OpenGL_fltk (0, menu_h, ww, hh, number ());
740 int toolbar_y = menu_h + hh + 1;
741 status =
new Fl_Output (5 * status_h + 1, toolbar_y,
742 ww - 5 * status_h - 1, status_h,
"");
744 status->textcolor (FL_BLACK);
745 status->color (FL_GRAY);
746 status->textfont (FL_COURIER);
747 status->textsize (10);
748 status->box (FL_ENGRAVED_BOX);
750 autoscale =
new Fl_Button (0, toolbar_y, status_h, status_h,
"A");
751 autoscale->callback (button_callback, static_cast<void*> (
this));
752 autoscale->tooltip (
"Autoscale");
754 togglegrid =
new Fl_Button (status_h, toolbar_y, status_h, status_h,
"G");
755 togglegrid->callback (button_callback, static_cast<void*> (
this));
756 togglegrid->tooltip (
"Toggle Grid");
758 panzoom =
new Fl_Button (2* status_h, toolbar_y, status_h, status_h,
"P");
759 panzoom->callback (button_callback, static_cast<void*> (
this));
760 panzoom->tooltip (
"Mouse Pan/Zoom");
762 rotate =
new Fl_Button (3 * status_h, toolbar_y, status_h, status_h,
"R");
763 rotate->callback (button_callback, static_cast<void*> (
this));
764 rotate->tooltip (
"Mouse Rotate");
766 help =
new Fl_Button (4 * status_h, toolbar_y, status_h, status_h,
"?");
767 help->callback (button_callback, static_cast<void*> (
this));
768 help->tooltip (
"Help");
774 if (fp.menubar_is (
"none") || !
uimenu->items_to_show ())
777 update_boundingbox (
internal);
779 if (fp.is_visible ())
791 #if defined (HAVE_X_WINDOWS)
792 std::string show_gui_msgs
796 if (show_gui_msgs.empty ())
797 XSetErrorHandler (xerror_handler);
800 if (fp.get_currentaxes ().ok ())
813 double number (
void) {
return fp.get___myhandle__ ().value (); }
815 void renumber (
double new_number)
819 if (canvas->renumber (new_number))
823 error (
"unable to renumber figure");
826 void print (
const std::string& cmd,
const std::string& term)
828 canvas->print (cmd, term);
831 void show_menubar (
void)
834 update_toolbar_position ();
837 void hide_menubar (
void)
840 update_toolbar_position ();
859 uimenu->remove_from_menu (uimenup);
863 uimenu->update_visible (uimenup);
867 uimenu->update_accelerator (uimenup);
871 uimenu->update_callback (uimenup);
875 uimenu->add_to_menu (figp);
879 uimenu->update_enable (uimenup);
883 uimenu->update_foregroundcolor (uimenup);
887 uimenu->add_to_menu (figp);
891 uimenu->add_to_menu (figp);
895 uimenu->update_seperator (uimenup);
899 if (
uimenu->items_to_show ())
906 void show_canvas (
void)
908 if (! canvas->can_do ())
909 error (
"unable to plot due to insufficient OpenGL support");
910 else if (fp.is_visible ())
913 canvas->make_current ();
917 void hide_canvas (
void)
926 void update_toolbar_position ()
928 int old_canvas_h = canvas->h ();
931 update_boundingbox (
true);
932 canvas->resize (0, menu_dy (),
w (), old_canvas_h);
934 int toolbar_y = canvas->h () + menu_dy () + 1;
935 autoscale->position (0, toolbar_y);
936 togglegrid->position (status_h, toolbar_y);
937 panzoom->position (2 * status_h, toolbar_y);
938 rotate->position (3 * status_h, toolbar_y);
939 help->position (4 * status_h, toolbar_y);
940 status->resize (5 * status_h + 1, toolbar_y,
941 w () - 5 * status_h - 1, status_h);
950 pos(1) += menu_dy ();
951 pos(3) -= menu_dy () + status_h + 2;
958 outerpos(1) -= menu_dy ();
959 outerpos(3) += menu_dy () + status_h + 2;
968 void update_boundingbox (
bool internal)
970 Matrix bb = fp.get_boundingbox (
internal);
972 bb = position2outerposition (bb);
973 resize (bb(0), bb(1), bb(2), bb(3));
976 void mark_modified (
void)
983 window_label = fp.get_title ();
984 label (window_label.c_str ());
991 plot_window (
const plot_window&);
993 plot_window& operator = (
const plot_window&);
997 std::string window_label;
1003 static const int status_h = 20;
1006 static const int menu_h = 25;
1009 static void window_close (Fl_Widget*,
void* data)
1012 args(0) =
static_cast<plot_window*
> (data)->number ();
1013 feval (
"close", args);
1017 static void button_callback (Fl_Widget* ww,
void* data)
1019 static_cast<plot_window*
> (data)->button_press (ww, data);
1022 void button_press (Fl_Widget* widg,
void*)
1024 if (widg == autoscale)
1026 else if (widg == togglegrid)
1028 else if (widg == panzoom)
1030 else if (widg == rotate)
1032 else if (widg == help)
1033 fl_message (
"%s", help_text);
1036 void set_on_ax_obj (
const std::string& name,
const std::string& value)
1039 if (ax_obj && ax_obj.isa (
"axes"))
1043 ap.
set (name, value);
1053 ap.
set (name, value);
1059 OpenGL_fltk* canvas;
1060 Fl_Button* autoscale;
1061 Fl_Button* togglegrid;
1066 Fl_Box* resize_dummy;
1072 void axis_auto (
void)
1079 feval (
"axis", args);
1084 void toggle_grid (
void)
1090 feval (
"grid", args);
1094 void pixel2pos (
const graphics_handle& ax,
int px,
int py,
double& xx,
1103 if (ax && ax.
isa (
"axes"))
1116 int len = kids.
length ();
1118 for (
int k = 0; k < len; k++)
1130 if (bb(0) <= px && px < (bb(0)+bb(2))
1131 && bb(1) <= py && py < (bb(1)+bb(3)))
1142 int px1 = -1,
int py1 = -1)
1148 int px1 = -1,
int py1 = -1)
1150 double x0, y0, x1, y1;
1152 std::stringstream cbuf;
1155 pixel2pos (ax, px0, py0, x0, y0);
1156 cbuf <<
"[" << x0 <<
", " << y0 <<
"]";
1159 pixel2pos (ax, px1, py1, x1, y1);
1160 cbuf <<
" -> ["<< x1 <<
", " << y1 <<
"]";
1163 status->value (cbuf.str ().c_str ());
1168 if (ax && ax.
isa (
"axes"))
1172 std::stringstream cbuf;
1177 cbuf <<
"[azimuth: " << v(0) <<
", elevation: " << v(1) <<
"]";
1179 status->value (cbuf.str ().c_str ());
1183 void set_currentpoint (
int px,
int py)
1225 if (uimenu->is_visible ())
1238 std::string key_str;
1239 std::ostringstream tmp_str;
1241 if (e_key == FL_Escape)
1243 else if (e_key == FL_Tab)
1245 else if (e_key == FL_Caps_Lock)
1246 key_str =
"capslock";
1247 else if (e_key == FL_Shift_L || e_key == FL_Shift_R)
1249 else if (e_key == FL_Control_L || e_key == FL_Control_R)
1250 key_str =
"control";
1251 else if (e_key == FL_Meta_L || e_key == FL_Meta_R)
1252 key_str =
"windows";
1253 else if (e_key == FL_Alt_L || e_key == FL_Alt_R)
1255 else if (e_key == 32)
1257 else if (e_key == FL_Enter)
1259 else if (e_key == FL_BackSpace)
1260 key_str =
"backspace";
1261 else if (e_key == FL_Print)
1262 key_str =
"printscreen";
1263 else if (e_key == FL_Pause)
1265 else if (e_key == FL_Home)
1267 else if (e_key == FL_End)
1269 else if (e_key == FL_Insert)
1271 else if (e_key == FL_Page_Up)
1273 else if (e_key == FL_Delete)
1275 else if (e_key == FL_Page_Down)
1276 key_str =
"pagedown";
1277 else if (e_key == FL_Left)
1278 key_str =
"leftarrow";
1279 else if (e_key == FL_Up)
1280 key_str =
"uparrow";
1281 else if (e_key == FL_Right)
1282 key_str =
"rightarrow";
1283 else if (e_key == FL_Down)
1284 key_str =
"downarrow";
1285 else if (e_key == FL_Num_Lock)
1286 key_str =
"numlock";
1287 else if (e_key == 0xffaf)
1289 else if (e_key == 0xffaa)
1290 key_str =
"multiply";
1291 else if (e_key == 0xffad)
1292 key_str =
"subtract";
1293 else if (e_key == 0xffab)
1295 else if (e_key == 0xff8d)
1297 else if (e_key == 0xffac)
1298 key_str =
"separator";
1299 else if (e_key >= 0xffb0 && e_key <= 0xffb9)
1301 tmp_str <<
"numpad" << (e_key - 0xffb0);
1302 key_str = tmp_str.str ();
1304 else if (e_key >= (FL_F + 1) && e_key <= (FL_F + 12))
1306 tmp_str <<
"f" << (e_key - FL_F);
1307 key_str = tmp_str.str ();
1309 else if (e_key ==
',')
1311 else if (e_key ==
'.')
1313 else if (e_key ==
'-')
1315 else if (e_key ==
'^' || e_key ==
'+' || e_key ==
'#'
1316 || e_key ==
'<' || e_key == 0xfe03 )
1318 else if (isalnum (e_key))
1319 key_str = std::tolower (e_key);
1320 else if (isprint (e_text[0]))
1327 Cell modifier2cell (
int e_state)
1331 if (e_state & FL_SHIFT)
1332 mod.
append (std::string (
"shift"));
1333 if (e_state & FL_CTRL)
1334 mod.
append (std::string (
"control"));
1335 if (e_state & FL_ALT)
1336 mod.
append (std::string (
"alt"));
1337 if (e_state & FL_COMMAND)
1338 mod.
append (std::string (
"command"));
1342 void resize (
int xx,
int yy,
int ww,
int hh)
1344 Fl_Window::resize (xx, yy, ww, hh);
1389 int handle (
int event)
1391 if (event == FL_FOCUS)
1403 static bool key_resent_detected =
false;
1410 static int last_event_key = 0;
1411 static char last_event_text = 0;
1413 int e_key = Fl::event_key ();
1414 char e_text = Fl::event_text ()[0];
1415 key_resent_detected = (e_key == last_event_key
1416 && std::tolower (last_event_text) == std::tolower (e_text)
1417 && ((islower (last_event_text) && isupper (e_text))
1418 || (isupper (last_event_text) && islower (e_text))));
1420 last_event_key = e_key;
1421 last_event_text = e_text;
1427 int e_key = Fl::event_key ();
1428 const char *e_text = Fl::event_text ();
1429 int e_state = Fl::event_state ();
1438 if (Fl::event_inside (canvas))
1440 pos_x = Fl::event_x ();
1441 pos_y = Fl::event_y () - menu_dy ();
1443 set_currentpoint (pos_x, pos_y);
1445 gh = pixel2axes_or_ca (pos_x, pos_y);
1450 set_axes_currentpoint (ax_obj, pos_x, pos_y);
1485 int e_key = Fl::event_key ();
1486 int e_state = Fl::event_state ();
1488 if (key_resent_detected && Fl::event_length () == 1)
1493 tmp_e_text[0] = Fl::event_text ()[0];
1496 if (std::islower (tmp_e_text[0]))
1497 tmp_e_text[0] = std::toupper (tmp_e_text[0]);
1499 tmp_e_text[0] = std::tolower (tmp_e_text[0]);
1500 evt = format_key_event (e_key, tmp_e_text, e_state);
1504 const char *e_text = Fl::event_text ();
1505 evt = format_key_event (e_key, e_text, e_state);
1517 if (Fl::event_inside (canvas))
1521 pixel2status (pixel2axes_or_ca (Fl::event_x (),
1522 Fl::event_y () - menu_dy ()),
1523 Fl::event_x (), Fl::event_y () - menu_dy ());
1527 pos_x = Fl::event_x ();
1528 pos_y = Fl::event_y () - menu_dy ();
1530 set_currentpoint (pos_x, pos_y);
1532 if (Fl::event_clicks ())
1534 else if (Fl::event_button () == FL_MIDDLE_MOUSE
1535 || (Fl::event_button () == FL_LEFT_MOUSE
1536 && Fl::event_shift ()))
1538 else if (Fl::event_button () == FL_RIGHT_MOUSE
1539 || (Fl::event_button () == FL_LEFT_MOUSE
1540 && Fl::event_ctrl ()))
1545 gh = pixel2axes_or_ca (pos_x, pos_y);
1550 set_axes_currentpoint (ax_obj, pos_x, pos_y);
1563 rotate->activate ();
1565 rotate->deactivate ();
1583 set_currentpoint (Fl::event_x (), Fl::event_y () - menu_dy ());
1587 if (Fl::event_button () == 1)
1589 if (ax_obj && ax_obj.
isa (
"axes"))
1596 if (ap.
get_tag ().compare (
"legend") < 0)
1599 view2status (ax_obj);
1601 pixel2status (ax_obj, pos_x, pos_y,
1603 Fl::event_y () - menu_dy ());
1605 double x0, y0, x1, y1;
1607 pixel2pos (ax_obj, pos_x, pos_y, x0, y0);
1608 pixel2pos (ax_obj, Fl::event_x (),
1609 Fl::event_y () - menu_dy (),
1621 daz = (Fl::event_x () - pos_x) / pos(2) * 360;
1622 del = (Fl::event_y () - menu_dy () - pos_y)
1631 pos(0) +=
double (Fl::event_x () - pos_x)
1633 pos(1) -=
double (Fl::event_y () - menu_dy () - pos_y)
1638 pos_x = Fl::event_x ();
1639 pos_y = Fl::event_y () - menu_dy ();
1644 else if (Fl::event_button () == 3)
1646 pixel2status (ax_obj, pos_x, pos_y,
1647 Fl::event_x (), Fl::event_y () - menu_dy ());
1649 zoom_box (0) = pos_x;
1650 zoom_box (1) = pos_y;
1651 zoom_box (2) = Fl::event_x ();
1652 zoom_box (3) = Fl::event_y () - menu_dy ();
1653 canvas->set_zoom_box (zoom_box);
1654 canvas->zoom (
true);
1667 if (ax && ax.
isa (
"axes"))
1676 const double factor = (Fl::event_dy () < 0
1677 ? 1 / (1.0 - wheel_zoom_speed)
1678 : 1.0 - wheel_zoom_speed);
1683 pixel2pos (ax, Fl::event_x (), Fl::event_y () - menu_dy (),
1697 set_currentpoint (Fl::event_x (), Fl::event_y () - menu_dy ());
1701 if ((Fl::event_button () == 1) && Fl::event_clicks ())
1704 set_on_ax_obj (
"xlimmode",
"auto");
1705 set_on_ax_obj (
"ylimmode",
"auto");
1706 set_on_ax_obj (
"zlimmode",
"auto");
1710 if (Fl::event_button () == 3)
1713 if (canvas->zoom ())
1715 canvas->zoom (
false);
1717 if (ax_obj && ax_obj.
isa (
"axes"))
1721 pixel2pos (ax_obj, pos_x, pos_y, x0, y0);
1722 int pos_x1 = Fl::event_x ();
1723 int pos_y1 = Fl::event_y () - menu_dy ();
1724 pixel2pos (ax_obj, pos_x1, pos_y1, x1, y1);
1727 int dx =
abs (pos_x - pos_x1);
1728 int dy =
abs (pos_y - pos_y1);
1730 if ((dx > 4) && (dy > 4))
1752 ap.
zoom (
"both", xl, yl);
1763 return Fl_Window::handle (event);
1767 class figure_manager
1771 static bool instance_ok (
void)
1776 instance =
new figure_manager ();
1780 ::error (
"unable to create figure_manager object!");
1788 ~figure_manager (
void)
1793 static void close_all (
void)
1796 instance->do_close_all ();
1802 instance->do_new_window (fp);
1805 static void delete_window (
int idx)
1808 instance->do_delete_window (idx);
1811 static void delete_window (
const std::string& idx_str)
1813 delete_window (str2idx (idx_str));
1816 static void renumber_figure (
const std::string& idx_str,
double new_number)
1819 instance->do_renumber_figure (str2idx (idx_str), new_number);
1822 static void toggle_window_visibility (
int idx,
bool is_visible)
1825 instance->do_toggle_window_visibility (idx, is_visible);
1828 static void toggle_window_visibility (
const std::string& idx_str,
1831 toggle_window_visibility (str2idx (idx_str), is_visible);
1834 static void mark_modified (
int idx)
1837 instance->do_mark_modified (idx);
1842 mark_modified (hnd2idx (gh));
1845 static void set_name (
int idx)
1848 instance->do_set_name (idx);
1851 static void set_name (
const std::string& idx_str)
1853 set_name (str2idx (idx_str));
1858 return instance_ok () ? instance->do_get_size (idx) :
Matrix ();
1867 const std::string& term)
1870 instance->do_print (hnd2idx (gh), cmd, term);
1877 instance->do_uimenu_update (hnd2idx (figh), uimenuh,
id);
1884 instance->do_update_canvas (hnd2idx (gh), ca);
1887 static void update_boundingbox (
const std::string& fig_idx_str,
1891 instance->do_update_boundingbox (str2idx (fig_idx_str),
internal);
1894 static void toggle_menubar_visibility (
const std::string& fig_idx_str,
1895 bool menubar_is_figure)
1898 instance->do_toggle_menubar_visibility (str2idx (fig_idx_str),
1904 static figure_manager *instance;
1906 figure_manager (
void) { }
1909 figure_manager (
const figure_manager&);
1910 figure_manager& operator = (
const figure_manager&);
1914 static int curr_index;
1915 typedef std::map<int, plot_window*> window_map;
1916 typedef window_map::iterator wm_iterator;;
1919 static std::string fltk_idx_header;
1921 void do_close_all (
void)
1924 for (win = windows.begin (); win != windows.end (); win++)
1931 int idx = figprops2idx (fp);
1933 if (idx >= 0 && windows.find (idx) == windows.end ())
1936 bool internal =
false;
1938 if (pos(2) != -1.0 && pos(3) != -1.0)
1949 idx2figprops (curr_index, fp);
1951 windows[curr_index++] =
new plot_window (pos(0), pos(1), pos(2), pos(3),
1956 void do_delete_window (
int idx)
1958 wm_iterator win = windows.find (idx);
1960 if (win != windows.end ())
1963 windows.erase (win);
1967 void do_renumber_figure (
int idx,
double new_number)
1969 wm_iterator win = windows.find (idx);
1971 if (win != windows.end ())
1972 win->second->renumber (new_number);
1975 void do_toggle_window_visibility (
int idx,
bool is_visible)
1977 wm_iterator win = windows.find (idx);
1979 if (win != windows.end ())
1983 win->second->show ();
1984 win->second->show_canvas ();
1987 win->second->hide ();
1992 void do_toggle_menubar_visibility (
int fig_idx,
bool menubar_is_figure)
1994 wm_iterator win = windows.find (fig_idx);
1996 if (win != windows.end ())
1998 if (menubar_is_figure)
1999 win->second->show_menubar ();
2001 win->second->hide_menubar ();
2003 win->second->redraw ();
2007 void do_mark_modified (
int idx)
2009 wm_iterator win = windows.find (idx);
2011 if (win != windows.end ())
2013 win->second->mark_modified ();
2017 void do_set_name (
int idx)
2019 wm_iterator win = windows.find (idx);
2021 if (win != windows.end ())
2022 win->second->set_name ();
2025 Matrix do_get_size (
int idx)
2029 wm_iterator win = windows.find (idx);
2031 if (win != windows.end ())
2033 sz(0) = win->second->w ();
2034 sz(1) = win->second->h ();
2040 void do_print (
int idx,
const std::string& cmd,
const std::string& term)
2042 wm_iterator win = windows.find (idx);
2044 if (win != windows.end ())
2045 win->second->print (cmd, term);
2050 wm_iterator win = windows.find (idx);
2052 if (win != windows.end ())
2053 win->second->uimenu_update (gh,
id);
2058 wm_iterator win = windows.find (idx);
2060 if (win != windows.end ())
2063 win->second->show_canvas ();
2065 win->second->hide_canvas ();
2069 void do_update_boundingbox (
int idx,
bool internal)
2071 wm_iterator win = windows.find (idx);
2073 if (win != windows.end ())
2074 win->second->update_boundingbox (
internal);
2080 if (clstr.find (fltk_idx_header,0) == 0)
2082 std::istringstream istr (clstr.substr (fltk_idx_header.size ()));
2086 error (
"figure_manager: could not recognize fltk index");
2092 std::ostringstream ind_str;
2093 ind_str << fltk_idx_header << idx;
2107 error (
"figure_manager: figure is not fltk");
2111 static int hnd2idx (
double h)
2114 if (fobj && fobj.
isa (
"figure"))
2118 return figprops2idx (fp);
2120 error (
"figure_manager: H (= %g) is not a figure", h);
2126 return hnd2idx (fh.
value ());
2130 figure_manager *figure_manager::instance = 0;
2132 std::string figure_manager::fltk_idx_header=
"fltk index=";
2133 int figure_manager::curr_index = 1;
2140 fltk_graphics_toolkit (
void)
2142 input_event_hook_fcn_id ()
2144 Fl::visual (FL_RGB);
2147 ~fltk_graphics_toolkit (
void) { }
2149 bool is_valid (
void)
const {
return true; }
2153 if (go.
isa (
"figure")
2154 || go.
isa (
"uimenu"))
2156 if (go.
isa (
"uimenu"))
2167 if (go.
isa (
"figure"))
2182 std::string fltk_label = uimenup.
get_label ();
2184 if (go.
isa (
"uimenu"))
2185 fltk_label = dynamic_cast<const uimenu::properties&>
2189 else if (go.
isa (
"figure") || go.
isa (
"uicontextmenu"))
2192 error (
"unexpected parent object\n");
2200 if (go.
isa (
"figure"))
2212 figure_manager::toggle_window_visibility (ov.
string_value (),
2217 figure_manager::toggle_menubar_visibility
2222 figure_manager::update_canvas (go.
get_handle (),
2235 figure_manager::renumber_figure (tmp, gh.
value ());
2236 figure_manager::set_name (tmp);
2241 figure_manager::update_boundingbox (ov.
string_value (),
true);
2245 figure_manager::update_boundingbox (ov.
string_value (),
false);
2250 else if (go.
isa (
"uimenu"))
2253 uimenu_set_fltk_label (go);
2264 if (obj && obj.
isa (
"root"))
2272 if (fobj && fobj.
isa (
"figure"))
2277 == FLTK_GRAPHICS_TOOLKIT_NAME)
2278 figure_manager::new_window (fp);
2283 figure_manager::mark_modified (go.
get_handle ());
2288 const std::string& term,
2289 const std::string& file_cmd,
bool ,
2290 const std::string& )
const
2292 figure_manager::print (go.
get_handle (), file_cmd, term);
2330 figure_manager::close_all ();
2336 input_event_hook_fcn_id = id;
2347 @deftypefn {Loadable Function} {} __fltk_check__ ()\n\
2348 Undocumented internal function. Calls Fl::check ()\n\
2357 error (
"__fltk_check__: not available without OpenGL and FLTK libraries");
2367 @deftypefn {Loadable Function} {} __init_fltk__ ()\n\
2368 Undocumented internal function.\n\
2373 error (
"__init_fltk__: no graphics DISPLAY available");
2374 else if (! toolkit_loaded)
2378 fltk_graphics_toolkit *fltk =
new fltk_graphics_toolkit ();
2381 toolkit_loaded =
true;
2387 fltk->set_input_event_hook_id (
id);
2390 error (
"__init_fltk__: not available without OpenGL and FLTK libraries");
2398 @deftypefn {Loadable Function} {@var{FLTK_available} =} __have_fltk__ ()\n\
2399 Undocumented internal function.\n\
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_value get_buttondownfcn(void) const
octave_idx_type numel(void) const
Number of elements in the array.
const octave_value & contents(const_iterator p) const
octave_value_list & append(const octave_value &val)
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)
octave_value_list feval(const std::string &name, const octave_value_list &args, int nargout)
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)
static bool rotate_enabled(const graphics_object figObj)
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
graphics_xform get_transform(void) const
void gl2ps_print(const graphics_object &fig, const std::string &cmd, const std::string &term)
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
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
bool is_string(void) const
void rotate_view(double delta_az, double delta_el, bool push_to_zoom_stack=true)
static std::string getenv(const std::string &name)
string_vector & append(const std::string &s)
octave_value get(bool all=false) const
base_properties & get_properties(void)
void set_position(const octave_value &val)
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)
size_t size(T const (&)[z])
graphics_object get_ancestor(const std::string &type) const
Matrix matrix_value(bool frc_str_conv=false) const
int calc_dimensions(const graphics_object &go)
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
octave_idx_type length(void) const
Number of elements in the array.
bool is_empty(void) const
ColumnVector pixel2coord(double px, double py) const
octave_scalar_map scalar_map_value(void) const
void assign(const std::string &k, const octave_value &val)
static bool display_available(void)
static graphics_handle lookup(double val)
static bool pan_enabled(const graphics_object figObj)
Matrix get_all_children(void) const
static graphics_object get_object(double val)
static int get_size(double d, const std::string &who)
graphics_handle get_parent(void) const
static std::string pan_mode(const graphics_object figObj)
#define DEFUN_DLD(name, args_name, nargout_name, doc)
std::complex< T > floor(const std::complex< T > &x)
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 munlock(const std::string &nm)
return octave_value(v1.char_array_value().concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string())? '\'': '"'))