# HG changeset patch # User Kai Habel # Date 1285308594 -7200 # Node ID f9a2aba512f862e78594dddd25a0d0cf8924451e # Parent a02a47f866d55e5d3cd543471c7b019d95f52a68 [mq]: uimenu.fltk diff -r a02a47f866d5 -r f9a2aba512f8 src/DLD-FUNCTIONS/fltk_backend.cc --- a/src/DLD-FUNCTIONS/fltk_backend.cc Fri Sep 24 08:04:29 2010 +0200 +++ b/src/DLD-FUNCTIONS/fltk_backend.cc Fri Sep 24 08:09:54 2010 +0200 @@ -35,17 +35,20 @@ #if defined (HAVE_FLTK) +#include #include #include #include -#include #include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include -#include -#include #include #include #include @@ -110,7 +113,14 @@ print_fid = fid; print_term = term; } - + + void resize (int xx, int yy, int ww, int hh) + { + Fl_Gl_Window::resize (xx, yy, ww, hh); + setup_viewport (ww, hh); + redraw (); + } + private: double number; opengl_renderer renderer; @@ -152,13 +162,6 @@ } } - void resize (int xx, int yy, int ww, int hh) - { - Fl_Gl_Window::resize (xx, yy, ww, hh); - setup_viewport (ww, hh); - redraw (); - } - void zoom_box_vertex (void) { glVertex2d (zoom_box(0), h () - zoom_box(1)); @@ -219,6 +222,12 @@ // Parameter controlling how fast we zoom when using the scrool wheel. static double wheel_zoom_speed = 0.05; +void script_cb(Fl_Widget*, void* data) +{ + uimenu::properties *up = static_cast (data); + up->execute_callback (); +} + class plot_window : public Fl_Window { public: @@ -228,21 +237,22 @@ panzoom (0), rotate (0), help (0), status (0) { callback (window_close, static_cast (this)); - begin (); { + + menubar = new + Fl_Menu_Bar(0, 0, ww, menu_h); + canvas = new - OpenGL_fltk (0, 0, ww , hh - status_h, number ()); - + OpenGL_fltk (0, menu_h, ww , hh - menu_h - status_h, number ()); + bottom = new Fl_Box (0, hh - status_h, ww, status_h); bottom->box(FL_FLAT_BOX); - ndim = calc_dimensions (gh_manager::get_object (fp.get___myhandle__ ())); - autoscale = new Fl_Button (0, hh - status_h, @@ -308,33 +318,40 @@ if (fp.is_visible ()) { show (); - canvas->show (); - canvas->make_current (); + //show_canvas (); + if (fp.get_currentaxes ().ok()) + show_canvas (); + else + hide_canvas (); } } end (); + status->show (); autoscale->show (); togglegrid->show (); panzoom->show (); rotate->show (); - + being_deleted = false; set_name (); resizable (canvas); size_range (4*status_h, 2*status_h); gui_mode = (ndim == 3 ? rotate_zoom : pan_zoom); + uimenu_update (); } ~plot_window (void) { canvas->hide (); status->hide (); + menubar->hide (); this->hide (); delete canvas; delete status; + delete menubar; } - + // FIXME -- this could change. double number (void) { return fp.get___myhandle__ ().value (); } @@ -348,6 +365,216 @@ Fl::wait (fltk_maxtime); } + template + Matrix find_uimenu_children (T& prop) const + { + + octave_idx_type k = 0; + + Matrix retval = prop.get_children (); + Matrix pos = Matrix(retval.numel (), 1); + + for (octave_idx_type ii = 0; ii < retval.numel (); ii++) + { + graphics_handle kid = retval (ii); + + if (gh_manager::is_handle_visible (kid)) + { + graphics_object kidgo = gh_manager::get_object (kid); + if (kidgo.isa ("uimenu")) + { + retval(k) = retval(ii); + pos(k++) = + dynamic_cast (kidgo.get_properties()).get_position (); + } + } + } + + retval.resize (k, 1); + pos.resize (k, 1); + Matrix ret = Matrix (k, 1); + // Don't know if this is the best method to sort. + Array sidx = pos.sort_rows_idx (DESCENDING); + for (octave_idx_type ii = 0; ii < k; ii++) + ret(ii) = retval(sidx(ii)); + + return ret; + } + + + void add_to_menu(graphics_object uimenu_obj, Fl_Menu_Bar* mb, std::string labelprefix, int postfix) + { + + if (uimenu_obj.valid_object () && uimenu_obj.isa ("uimenu")) + { + + uimenu::properties& uimenup = + dynamic_cast (uimenu_obj.get_properties ()); + + int menuflags = 0; + if (uimenup.is_separator ()) + { + // It seems matlab places the separator before the current + // menu entry, while fltk places it after. So we need to find + // the previous item in this menu/submenu. (Kai) + + int itemflags = 0,ii = -1; + for (ii = mb->size() - 1; ii >= 0; ii--) + { + Fl_Menu_Item* item = const_cast(&menubar->menu () [ii]); + itemflags = item->flags; //Direct access to structure! + if (item->label()!=NULL) + break; + } + if (ii >= 0 && !(itemflags & FL_SUBMENU)) + mb->mode(ii,itemflags | FL_MENU_DIVIDER); + //menuflags += FL_MENU_DIVIDER; + } + + Matrix uimenu_ch = find_uimenu_children (uimenup); + + int len = uimenu_ch.numel (); + + if (len > 0) + menuflags += FL_SUBMENU; + + else if ((len == 0) && uimenup.is_checked ()) + menuflags += FL_MENU_TOGGLE + FL_MENU_VALUE; + + if (!uimenup.is_enable ()) + menuflags += FL_MENU_INACTIVE; + + if (!uimenup.is_visible ()) + menuflags += FL_MENU_INVISIBLE; + + std::string mylabel = labelprefix + uimenup.get_label (); + if (postfix) + { + std::ostringstream os; + os << "(" << postfix << ")"; + mylabel += os.str(); + } + std::string acc = uimenup.get_accelerator (); + + int key = 0; + if (acc.length() != 0) + key = FL_CTRL + acc[0]; + + const Fl_Menu_Item* item = mb->find_item(mylabel.c_str ()); + + if (item == NULL) + { + if (!uimenup.is_beingdeleted ()) + { + mb->add(mylabel.c_str (), // label + key, //accelerator key + static_cast(script_cb), //callback + static_cast(&uimenup), //callback data + menuflags); + //set text color + Fl_Menu_Item* newitem = + const_cast(mb->find_item(mylabel.c_str ())); + Matrix rgb = uimenup.get_foregroundcolor_rgb(); + newitem->labelcolor(fl_rgb_color(static_cast(floor(rgb(0)*255)), + static_cast(floor(rgb(1)*255)), + static_cast(floor(rgb(2)*255)))); + } + } + else + { + //Since FLTK (v1.10) does not allow for two menu entries + //with the same label, we append an integer value to the original + //label. The label property remains unchanged. (Kai) + postfix++; + add_to_menu(uimenu_obj, mb, labelprefix, postfix); + } + + if (len > 0) + labelprefix = mylabel + '/'; + + for (octave_idx_type ii = 0; ii < len; ii++) + { + graphics_handle kid = uimenu_ch (len - (ii + 1)); + graphics_object kgo = gh_manager::get_object (kid); + + if (kgo.valid_object ()) + add_to_menu(kgo, mb, labelprefix, postfix); + + } + } + } + + void uimenu_update(void) + { + int ui = 0; + + menubar->clear(); + delete_menubar (); + if (!fp.is_beingdeleted ()) + { + Matrix kids = find_uimenu_children (fp); + + int len = kids.length (); + int postfix = 0; + + for (int k = 0; k < len; k++) + { + graphics_object kid = gh_manager::get_object (kids(len - (k + 1))); + if (kid.valid_object () && (!kid.get_properties ().is_beingdeleted ())) + { + add_to_menu(kid, menubar, "", postfix); + ui++; + } + } + } + + if (ui > 0) + create_menubar (); + else + delete_menubar (); + + mark_modified (); + } + + void create_menubar (void) + { + int dm = menu_h; + if (menubar->visible ()) + dm = 0; + + canvas->resize (canvas->x (), + canvas->y () + dm, + canvas->w (), + canvas->h () - dm); + menubar->show (); + mark_modified (); + } + + void delete_menubar (void) + { + int dm = menu_h; + if (!menubar->visible ()) + dm = 0; + + canvas->resize (canvas->x (), + canvas->y () - dm, + canvas->w (), + canvas->h () + dm); + menubar->hide (); + mark_modified (); + } + + void show_canvas (void) + { + canvas->show (); + canvas->make_current (); + } + + void hide_canvas (void) + { + canvas->hide (); + } + void mark_modified (void) { damage (FL_DAMAGE_ALL); @@ -368,7 +595,8 @@ window_label = fp.get_title (); label (window_label.c_str ()); } - + + bool being_deleted; private: // window name -- this must exists for the duration of the window's // life @@ -389,6 +617,9 @@ // Status area height. static const int status_h = 20; + // Menubar height. + static const int menu_h = 20; + // Window callback. static void window_close (Fl_Widget*, void* data) { @@ -400,10 +631,10 @@ // Button callbacks. static void button_callback (Fl_Widget* ww, void* data) { - static_cast (data)->button_press (ww); + static_cast (data)->button_press (ww, data); } - void button_press (Fl_Widget* widg) + void button_press (Fl_Widget* widg, void*) { if (widg == autoscale) axis_auto (); @@ -429,7 +660,8 @@ Fl_Button* rotate; Fl_Button* help; Fl_Output* status; - + Fl_Menu_Bar* menubar; + void axis_auto (void) { octave_value_list args; @@ -442,9 +674,11 @@ void toggle_grid (void) { octave_value_list args; - args(0) = fp.get_currentaxes ().as_octave_value (); + if (fp.get_currentaxes ().ok ()) + args(0) = fp.get_currentaxes ().as_octave_value (); + feval ("grid", args); - mark_modified (); + mark_modified (); } void pixel2pos @@ -539,15 +773,18 @@ void set_currentpoint (int px, int py) { - Matrix pos (1,2,0); - pos(0) = px; - pos(1) = h () - status_h - py; - fp.set_currentpoint (pos); + if (!fp.is_beingdeleted ()) + { + Matrix pos (1,2,0); + pos(0) = px; + pos(1) = h () - status_h - menu_h - py; + fp.set_currentpoint (pos); + } } void set_axes_currentpoint (graphics_object ax, int px, int py) { - if (ax) + if (ax.valid_object ()) { axes::properties& ap = dynamic_cast (ax.get_properties ()); @@ -609,261 +846,280 @@ void resize (int xx,int yy,int ww,int hh) { - Fl_Window::resize (xx, yy, ww, hh); + if (!being_deleted) + { + Fl_Window::resize (xx, yy, ww, hh); - Matrix pos (1,4,0); - pos(0) = xx; - pos(1) = yy; - pos(2) = ww; - pos(3) = hh - status_h; + Matrix pos (1,4,0); + pos(0) = xx; + pos(1) = yy; + pos(2) = ww; + pos(3) = hh - status_h - menu_h; - fp.set_position (pos); + fp.set_position (pos); + } } void draw (void) { - Matrix pos = fp.get_position ().matrix_value (); - Fl_Window::resize (pos(0), pos(1) , pos(2), pos(3) + status_h); - - return Fl_Window::draw (); + if (!being_deleted) + { + Matrix pos = fp.get_position ().matrix_value (); + Fl_Window::resize (pos(0), pos(1) , pos(2), pos(3) + status_h + menu_h); + + return Fl_Window::draw (); + } } int handle (int event) - { + { static int px0,py0; static graphics_object ax0; + graphics_handle gh; + + int retval = Fl_Window::handle (event); + + // We only handle events which are in the canvas area. + if (!Fl::event_inside(canvas)) + return retval; + + if (!being_deleted) + { + switch (event) + { + case FL_KEYDOWN: + { + int key = Fl::event_key (); - int retval = Fl_Window::handle (event); + shift |= key2shift (key); + int key_a = key2ascii (key); + if (key_a && fp.get_keypressfcn ().is_defined ()) + { + Octave_map evt; + evt.assign ("Character", octave_value (key_a)); + evt.assign ("Key", octave_value (std::tolower (key_a))); + evt.assign ("Modifier", octave_value (modifier2cell ())); + fp.execute_keypressfcn (evt); + } + switch (key) + { + case 'a': + case 'A': + axis_auto (); + break; - // We only handle events which are in the canvas area. - if (Fl::event_y () >= h() - status_h) - return retval; + case 'g': + case 'G': + toggle_grid (); + break; - switch (event) - { - case FL_KEYDOWN: - { - int key = Fl::event_key (); + case 'p': + case 'P': + gui_mode = pan_zoom; + break; - shift |= key2shift (key); - int key_a = key2ascii (key); - if (key_a && fp.get_keypressfcn ().is_defined ()) - { - Octave_map evt; - evt.assign ("Character", octave_value (key_a)); - evt.assign ("Key", octave_value (std::tolower (key_a))); - evt.assign ("Modifier", octave_value (modifier2cell ())); - fp.execute_keypressfcn (evt); + case 'r': + case 'R': + gui_mode = rotate_zoom; + break; + } } - switch (key) - { - case 'a': - case 'A': - axis_auto (); break; - case 'g': - case 'G': - toggle_grid (); + case FL_KEYUP: + { + int key = Fl::event_key (); + + shift &= (~key2shift (key)); + int key_a = key2ascii (key); + if (key_a && fp.get_keyreleasefcn ().is_defined ()) + { + Octave_map evt; + evt.assign ("Character", octave_value (key_a)); + evt.assign ("Key", octave_value (std::tolower (key_a))); + evt.assign ("Modifier", octave_value (modifier2cell ())); + fp.execute_keyreleasefcn (evt); + } + } break; - case 'p': - case 'P': - gui_mode = pan_zoom; + case FL_MOVE: + pixel2status (pixel2axes_or_ca (Fl::event_x (), Fl::event_y ()), + Fl::event_x (), Fl::event_y ()); break; - case 'r': - case 'R': - if (ndim == 3) - gui_mode = rotate_zoom; - else - gui_mode = pan_zoom; + case FL_PUSH: + if (!being_deleted) { + + px0 = Fl::event_x (); + py0 = Fl::event_y (); + + set_currentpoint (Fl::event_x (), Fl::event_y ()); + + + gh = pixel2axes_or_ca (px0, py0); + + if (gh.ok ()) + { + ax0 = gh_manager::get_object (gh); + set_axes_currentpoint (ax0, px0, py0); + } + + + fp.execute_windowbuttondownfcn (); + + } + if (Fl::event_button () == 1 || Fl::event_button () == 3) + return 1; + break; - } - } - break; - case FL_KEYUP: - { - int key = Fl::event_key (); - - shift &= (~key2shift (key)); - int key_a = key2ascii (key); - if (key_a && fp.get_keyreleasefcn ().is_defined ()) - { - Octave_map evt; - evt.assign ("Character", octave_value (key_a)); - evt.assign ("Key", octave_value (std::tolower (key_a))); - evt.assign ("Modifier", octave_value (modifier2cell ())); - fp.execute_keyreleasefcn (evt); - } - } - break; - - case FL_MOVE: - pixel2status (pixel2axes_or_ca (Fl::event_x (), Fl::event_y ()), - Fl::event_x (), Fl::event_y ()); - break; - - case FL_PUSH: - px0 = Fl::event_x (); - py0 = Fl::event_y (); - ax0 = gh_manager::get_object (pixel2axes_or_ca (px0, py0)); - - set_currentpoint (Fl::event_x (), Fl::event_y ()); - set_axes_currentpoint (ax0, px0, py0); - fp.execute_windowbuttondownfcn (); - - - if (Fl::event_button () == 1 || Fl::event_button () == 3) - return 1; - break; - - case FL_DRAG: - if (fp.get_windowbuttonmotionfcn ().is_defined ()) - { - set_currentpoint (Fl::event_x (), Fl::event_y ()); - fp.execute_windowbuttonmotionfcn (); - } - - if (Fl::event_button () == 1) - { - if (ax0 && ax0.isa ("axes")) + case FL_DRAG: + if (fp.get_windowbuttonmotionfcn ().is_defined ()) { - if (gui_mode == pan_zoom) - pixel2status (ax0, px0, py0, Fl::event_x (), Fl::event_y ()); - else - view2status (ax0); - axes::properties& ap = - dynamic_cast (ax0.get_properties ()); - - double x0, y0, x1, y1; - Matrix pos = fp.get_position ().matrix_value (); - pixel2pos (ax0, px0, py0, x0, y0); - pixel2pos (ax0, Fl::event_x (), Fl::event_y (), x1, y1); - - if (gui_mode == pan_zoom) - ap.translate_view (x0 - x1, y0 - y1); - else if (gui_mode == rotate_zoom) - { - double daz, del; - daz = (Fl::event_x () - px0) / pos(2) * 360; - del = (Fl::event_y () - py0) / pos(3) * 360; - ap.rotate_view (del, daz); - } - - px0 = Fl::event_x (); - py0 = Fl::event_y (); - mark_modified (); + set_currentpoint (Fl::event_x (), Fl::event_y ()); + fp.execute_windowbuttonmotionfcn (); } - return 1; - } - else if (Fl::event_button () == 3) - { - pixel2status (ax0, px0, py0, Fl::event_x (), Fl::event_y ()); - Matrix zoom_box (1,4,0); - zoom_box (0) = px0; - zoom_box (1) = py0; - zoom_box (2) = Fl::event_x (); - zoom_box (3) = Fl::event_y (); - canvas->set_zoom_box (zoom_box); - canvas->zoom (true); - canvas->redraw (); - } - - break; - - case FL_MOUSEWHEEL: - { - graphics_object ax = - gh_manager::get_object (pixel2axes_or_ca (Fl::event_x (), - Fl::event_y ())); - if (ax && ax.isa ("axes")) - { - axes::properties& ap = - dynamic_cast (ax.get_properties ()); - - // Determine if we're zooming in or out. - const double factor = - (Fl::event_dy () > 0) ? 1.0 + wheel_zoom_speed : 1.0 - wheel_zoom_speed; - - // Get the point we're zooming about. - double x1, y1; - pixel2pos (ax, Fl::event_x (), Fl::event_y (), x1, y1); - - ap.zoom_about_point (x1, y1, factor, false); - mark_modified (); - } - } - return 1; - - case FL_RELEASE: - if (fp.get_windowbuttonupfcn ().is_defined ()) - { - set_currentpoint (Fl::event_x (), Fl::event_y ()); - fp.execute_windowbuttonupfcn (); - } - - if (Fl::event_button () == 1) - { - if ( Fl::event_clicks () == 1) + + if (Fl::event_button () == 1) { if (ax0 && ax0.isa ("axes")) { - axes::properties& ap = + if (gui_mode == pan_zoom) + pixel2status (ax0, px0, py0, Fl::event_x (), Fl::event_y ()); + else + view2status (ax0); + axes::properties& ap = dynamic_cast (ax0.get_properties ()); - ap.set_xlimmode("auto"); - ap.set_ylimmode("auto"); - ap.set_zlimmode("auto"); + + double x0, y0, x1, y1; + Matrix pos = fp.get_position ().matrix_value (); + pixel2pos (ax0, px0, py0, x0, y0); + pixel2pos (ax0, Fl::event_x (), Fl::event_y (), x1, y1); + + if (gui_mode == pan_zoom) + ap.translate_view (x0 - x1, y0 - y1); + else if (gui_mode == rotate_zoom) + { + double daz, del; + daz = (Fl::event_x () - px0) / pos(2) * 360; + del = (Fl::event_y () - py0) / pos(3) * 360; + ap.rotate_view (del, daz); + } + + px0 = Fl::event_x (); + py0 = Fl::event_y (); mark_modified (); } + return 1; } - } - if (Fl::event_button () == 3) - { - // End of drag -- zoom. - if (canvas->zoom ()) + else if (Fl::event_button () == 3) { - canvas->zoom (false); - double x0,y0,x1,y1; - if (ax0 && ax0.isa ("axes")) + pixel2status (ax0, px0, py0, Fl::event_x (), Fl::event_y ()); + Matrix zoom_box (1,4,0); + zoom_box (0) = px0; + zoom_box (1) = py0; + zoom_box (2) = Fl::event_x (); + zoom_box (3) = Fl::event_y (); + canvas->set_zoom_box (zoom_box); + canvas->zoom (true); + canvas->redraw (); + } + + break; + + case FL_MOUSEWHEEL: + { + graphics_object ax = + gh_manager::get_object (pixel2axes_or_ca (Fl::event_x (), + Fl::event_y ())); + if (ax && ax.isa ("axes")) + { + axes::properties& ap = + dynamic_cast (ax.get_properties ()); + + // Determine if we're zooming in or out. + const double factor = + (Fl::event_dy () > 0) ? 1.0 + wheel_zoom_speed : 1.0 - wheel_zoom_speed; + + // Get the point we're zooming about. + double x1, y1; + pixel2pos (ax, Fl::event_x (), Fl::event_y (), x1, y1); + + ap.zoom_about_point (x1, y1, factor, false); + mark_modified (); + } + } + return 1; + + case FL_RELEASE: + if (fp.get_windowbuttonupfcn ().is_defined ()) + { + set_currentpoint (Fl::event_x (), Fl::event_y ()); + fp.execute_windowbuttonupfcn (); + } + + if (Fl::event_button () == 1) + { + if ( Fl::event_clicks () == 1) { - axes::properties& ap = - dynamic_cast (ax0.get_properties ()); - pixel2pos (ax0, px0, py0, x0, y0); - pixel2pos (ax0, Fl::event_x (), Fl::event_y (), x1, y1); - Matrix xl (1,2,0); - Matrix yl (1,2,0); - if (x0 < x1) + if (ax0 && ax0.isa ("axes")) { - xl(0) = x0; - xl(1) = x1; + axes::properties& ap = + dynamic_cast (ax0.get_properties ()); + ap.set_xlimmode("auto"); + ap.set_ylimmode("auto"); + ap.set_zlimmode("auto"); + mark_modified (); } - else - { - xl(0) = x1; - xl(1) = x0; - } - if (y0 < y1) - { - yl(0) = y0; - yl(1) = y1; - } - else - { - yl(0) = y1; - yl(1) = y0; - } - ap.zoom (xl, yl); - mark_modified (); } } + if (Fl::event_button () == 3) + { + // End of drag -- zoom. + if (canvas->zoom ()) + { + canvas->zoom (false); + double x0,y0,x1,y1; + if (ax0 && ax0.isa ("axes")) + { + axes::properties& ap = + dynamic_cast (ax0.get_properties ()); + pixel2pos (ax0, px0, py0, x0, y0); + pixel2pos (ax0, Fl::event_x (), Fl::event_y (), x1, y1); + Matrix xl (1,2,0); + Matrix yl (1,2,0); + if (x0 < x1) + { + xl(0) = x0; + xl(1) = x1; + } + else + { + xl(0) = x1; + xl(1) = x0; + } + if (y0 < y1) + { + yl(0) = y0; + yl(1) = y1; + } + else + { + yl(0) = y1; + yl(1) = y0; + } + ap.zoom (xl, yl); + mark_modified (); + } + } + } + break; } - break; } - return retval; } + }; class figure_manager @@ -964,6 +1220,35 @@ instance->do_print (hnd2idx(gh), fid, term); } + static void update_uimenu (const graphics_handle& gh) + { + if (instance_ok ()) + instance->do_update_uimenu (hnd2idx(gh)); + } + + static void update_canvas (const graphics_handle& gh, const graphics_handle& ca) + { + if (instance_ok ()) + instance->do_update_canvas (hnd2idx(gh), ca); + } + + static void set_beingdeleted (const graphics_handle& gh) + { + if (instance_ok ()) + instance->do_set_beingdeleted (hnd2idx(gh)); + } + + static void toggle_menubar_visibility (int fig_idx, bool menubar_is_figure) + { + if (instance_ok ()) + instance->do_toggle_menubar_visibility (fig_idx, menubar_is_figure); + } + + static void toggle_menubar_visibility (std::string fig_idx_str, bool menubar_is_figure) + { + toggle_menubar_visibility (str2idx (fig_idx_str), menubar_is_figure); + } + private: static figure_manager *instance; @@ -1028,6 +1313,20 @@ } } + void do_toggle_menubar_visibility (int fig_idx, bool menubar_is_figure) + { + wm_iterator win; + if ((win = windows.find (fig_idx)) != windows.end ()) + { + if (menubar_is_figure) + win->second->create_menubar (); + else + win->second->delete_menubar (); + + win->second->redraw (); + } + } + void do_mark_modified (int idx) { wm_iterator win; @@ -1068,7 +1367,35 @@ win->second->print (fid, term); } } - + + void do_update_uimenu (int idx) + { + wm_iterator win; + if ((win = windows.find (idx)) != windows.end ()) + { + win->second->uimenu_update (); + } + } + + void do_update_canvas (int idx, graphics_handle ca) + { + wm_iterator win; + if ((win = windows.find (idx)) != windows.end ()) + { + if (ca.ok ()) + win->second->show_canvas (); + else + win->second->hide_canvas (); + } + } + + void do_set_beingdeleted (int idx) + { + wm_iterator win; + if ((win = windows.find (idx)) != windows.end ()) + win->second->being_deleted = true; + } + // FIXME -- default size should be configurable. void default_size (int& x, int& y, int& w, int& h) { @@ -1171,6 +1498,29 @@ return 0; } +//We should use xget_ancestor here, but I don't know how (Kai) +//extern xget_ancestor (const graphics_object&, const std::string&); + +static graphics_object +my_xget_ancestor (const graphics_object& go_arg, const std::string& type) +{ + graphics_object go = go_arg; + + do + { + if (go.valid_object ()) + { + if (go.isa (type)) + return go; + else + go = gh_manager::get_object (go.get_parent ()); + } + else + return graphics_object (); + } + while (true); +} + class fltk_backend : public base_graphics_backend { public: @@ -1186,14 +1536,13 @@ if (go.isa ("figure")) { octave_value ov = go.get (caseless_str ("__plot_stream__")); - - if (! ov.is_empty ()) - figure_manager::delete_window (ov.string_value ()); + figure_manager::delete_window (ov.string_value ()); } } void update (const graphics_object& go, int id) { + //printf("property id: %d changed for go: %s\n", id,go.type ().c_str ()); if (go.isa ("figure")) { octave_value ov = go.get (caseless_str ("__plot_stream__")); @@ -1205,17 +1554,30 @@ switch (id) { - case base_properties::VISIBLE: - figure_manager::toggle_window_visibility (ov.string_value (), fp.is_visible ()); - break; - - case figure::properties::NAME: - case figure::properties::NUMBERTITLE: - figure_manager::set_name (ov.string_value ()); - break; + case base_properties::VISIBLE: + figure_manager::toggle_window_visibility (ov.string_value (), fp.is_visible ()); + break; + case figure::properties::MENUBAR: + figure_manager::toggle_menubar_visibility (ov.string_value (), fp.menubar_is("figure")); + break; + case figure::properties::NAME: + case figure::properties::CURRENTAXES: + figure_manager::update_canvas (go.get_handle (), fp.get_currentaxes ()); + break; + case figure::properties::NUMBERTITLE: + figure_manager::set_name (ov.string_value ()); + break; + case figure::properties::BEINGDELETED: + figure_manager::set_beingdeleted (go.get_handle ()); + break; } } } + else if (go.isa ("uimenu")) + { + graphics_object fig = my_xget_ancestor(go,"figure"); + figure_manager::update_uimenu (fig.get_handle ()); + } } void redraw_figure (const graphics_object& go) const