Browse Source

Graphs menu

David Rose 20 years ago
parent
commit
2f0857570c

+ 1 - 1
pandatool/src/gtk-stats/Sources.pp

@@ -14,6 +14,7 @@
 
   #define SOURCES \
     gtkStats.cxx \
+    gtkStatsChartMenu.cxx gtkStatsChartMenu.h \
     gtkStatsGraph.cxx gtkStatsGraph.h \
     gtkStatsLabel.cxx gtkStatsLabel.h \
     gtkStatsLabelStack.cxx gtkStatsLabelStack.h \
@@ -22,7 +23,6 @@
     gtkStatsServer.cxx gtkStatsServer.h \
     gtkStatsStripChart.cxx gtkStatsStripChart.h
 
-//     gtkStatsChartMenu.cxx gtkStatsChartMenu.h \
 //     gtkStatsPianoRoll.cxx gtkStatsPianoRoll.h \
 
   #if $[DEVELOP_GTKSTATS]

+ 11 - 0
pandatool/src/gtk-stats/gtkStats.cxx

@@ -39,8 +39,19 @@ destroy(GtkWidget *widget, gpointer data) {
 
 static gboolean
 timer(gpointer data) {
+  static int count = 0;
   server->poll();
 
+  if (++count == 5) {
+    count = 0;
+    // Every once in a while, say once a second, we call this
+    // function, which should force gdk to make all changes visible.
+    // We do this in case we are getting starved and falling behind,
+    // so that the user still gets a chance to see *something* happen
+    // onscreen, even if it's just increasingly old data.
+    gdk_window_process_all_updates();
+  }
+
   return TRUE;
 }
 

+ 66 - 38
pandatool/src/gtk-stats/gtkStatsChartMenu.cxx

@@ -29,7 +29,8 @@ GtkStatsChartMenu(GtkStatsMonitor *monitor, int thread_index) :
   _monitor(monitor),
   _thread_index(thread_index)
 {
-  _menu = CreatePopupMenu();
+  _menu = gtk_menu_new();
+  gtk_widget_show(_menu);
   do_update();
 }
 
@@ -43,13 +44,13 @@ GtkStatsChartMenu::
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GtkStatsChartMenu::get_menu_handle
+//     Function: GtkStatsChartMenu::get_menu_widget
 //       Access: Public
-//  Description: Returns the Windows menu handle for this particular
+//  Description: Returns the gtk widget for this particular
 //               menu.
 ////////////////////////////////////////////////////////////////////
-HMENU GtkStatsChartMenu::
-get_menu_handle() {
+GtkWidget *GtkStatsChartMenu::
+get_menu_widget() {
   return _menu;
 }
 
@@ -59,7 +60,7 @@ get_menu_handle() {
 //  Description: Adds the menu to the end of the indicated menu bar.
 ////////////////////////////////////////////////////////////////////
 void GtkStatsChartMenu::
-add_to_menu_bar(HMENU menu_bar, int before_menu_id) {
+add_to_menu_bar(GtkWidget *menu_bar, int before_menu_id) {
   const PStatClientData *client_data = _monitor->get_client_data();
   string thread_name;
   if (_thread_index == 0) {
@@ -69,15 +70,11 @@ add_to_menu_bar(HMENU menu_bar, int before_menu_id) {
     thread_name = client_data->get_thread_name(_thread_index);
   }
 
-  MENUITEMINFO mii;
-  memset(&mii, 0, sizeof(mii));
-  mii.cbSize = sizeof(mii);
+  GtkWidget *menu_item = gtk_menu_item_new_with_label(thread_name.c_str());
+  gtk_widget_show(menu_item);
+  gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), _menu);
 
-  mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_SUBMENU; 
-  mii.fType = MFT_STRING; 
-  mii.hSubMenu = _menu; 
-  mii.dwTypeData = (char *)thread_name.c_str(); 
-  InsertMenuItem(menu_bar, before_menu_id, FALSE, &mii);
+  gtk_menu_bar_append(GTK_MENU_BAR(menu_bar), menu_item);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -107,10 +104,7 @@ do_update() {
   _last_level_index = view.get_level_index();
 
   // First, remove all of the old entries from the menu.
-  int num_items = GetMenuItemCount(_menu);
-  for (int i = num_items - 1; i >= 0; i--) {
-    DeleteMenu(_menu, i, MF_BYPOSITION);
-  }
+  gtk_container_foreach(GTK_CONTAINER(_menu), remove_menu_child, _menu);
 
   // Now rebuild the menu with the new set of entries.
 
@@ -118,9 +112,6 @@ do_update() {
   add_view(_menu, view.get_top_level(), false);
 
   bool needs_separator = true;
-  MENUITEMINFO mii;
-  memset(&mii, 0, sizeof(mii));
-  mii.cbSize = sizeof(mii);
 
   // And then the menu item(s) for each of the level values.
   const PStatClientData *client_data = _monitor->get_client_data();
@@ -133,9 +124,11 @@ do_update() {
       // We put a separator between the above frame collector and the
       // first level collector.
       if (needs_separator) {
+	/*
         mii.fMask = MIIM_FTYPE; 
         mii.fType = MFT_SEPARATOR; 
         InsertMenuItem(_menu, GetMenuItemCount(_menu), TRUE, &mii);
+	*/
 
         needs_separator = false;
       }
@@ -145,6 +138,7 @@ do_update() {
     }
   }
 
+  /*
   // Also a menu item for a piano roll (following a separator).
   mii.fMask = MIIM_FTYPE; 
   mii.fType = MFT_SEPARATOR; 
@@ -158,6 +152,7 @@ do_update() {
   mii.wID = menu_id;
   mii.dwTypeData = "Piano Roll";
   InsertMenuItem(_menu, GetMenuItemCount(_menu), TRUE, &mii);
+  */
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -167,37 +162,36 @@ do_update() {
 //               indicated view and its children.
 ////////////////////////////////////////////////////////////////////
 void GtkStatsChartMenu::
-add_view(HMENU parent_menu, const PStatViewLevel *view_level, bool show_level) {
+add_view(GtkWidget *parent_menu, const PStatViewLevel *view_level, 
+	 bool show_level) {
   int collector = view_level->get_collector();
 
   const PStatClientData *client_data = _monitor->get_client_data();
   string collector_name = client_data->get_collector_name(collector);
 
-  GtkStatsMonitor::MenuDef menu_def(_thread_index, collector, show_level);
-  int menu_id = _monitor->get_menu_id(menu_def);
+  GtkStatsMonitor::MenuDef smd(_thread_index, collector, show_level);
+  const GtkStatsMonitor::MenuDef *menu_def = _monitor->add_menu(smd);
 
-  MENUITEMINFO mii;
-  memset(&mii, 0, sizeof(mii));
-  mii.cbSize = sizeof(mii);
+  GtkWidget *menu_item = gtk_menu_item_new_with_label(collector_name.c_str());
+  gtk_widget_show(menu_item);
+  gtk_menu_shell_append(GTK_MENU_SHELL(parent_menu), menu_item);
 
-  mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID; 
-  mii.fType = MFT_STRING; 
-  mii.wID = menu_id;
-  mii.dwTypeData = (char *)collector_name.c_str(); 
-  InsertMenuItem(parent_menu, GetMenuItemCount(parent_menu), TRUE, &mii);
+  g_signal_connect_swapped(G_OBJECT(menu_item), "activate", 
+			   G_CALLBACK(handle_menu), (void *)(const void *)menu_def);
 
   int num_children = view_level->get_num_children();
   if (num_children > 1) {
     // If the collector has more than one child, add a menu entry to go
     // directly to each of its children.
-    HMENU submenu = CreatePopupMenu();
     string submenu_name = collector_name + " components";
 
-    mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_SUBMENU;
-    mii.fType = MFT_STRING; 
-    mii.hSubMenu = submenu;
-    mii.dwTypeData = (char *)submenu_name.c_str(); 
-    InsertMenuItem(parent_menu, GetMenuItemCount(parent_menu), TRUE, &mii);
+    GtkWidget *submenu_item = gtk_menu_item_new_with_label(submenu_name.c_str());
+    gtk_widget_show(submenu_item);
+    gtk_menu_shell_append(GTK_MENU_SHELL(parent_menu), submenu_item);
+
+    GtkWidget *submenu = gtk_menu_new();
+    gtk_widget_show(submenu);
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(submenu_item), submenu);
 
     // Reverse the order since the menus are listed from the top down;
     // we want to be visually consistent with the graphs, which list
@@ -207,3 +201,37 @@ add_view(HMENU parent_menu, const PStatViewLevel *view_level, bool show_level) {
     }
   }
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: GtkStatsChartMenu::handle_menu
+//       Access: Private, Static
+//  Description: Callback when a menu item is selected.
+////////////////////////////////////////////////////////////////////
+void GtkStatsChartMenu::
+handle_menu(gpointer data) {
+  const GtkStatsMonitor::MenuDef *menu_def = (GtkStatsMonitor::MenuDef *)data;
+  GtkStatsMonitor *monitor = menu_def->_monitor;
+
+  if (monitor == NULL) {
+    return;
+  }
+
+  if (menu_def->_collector_index < 0) {
+    monitor->open_piano_roll(menu_def->_thread_index);
+  } else {
+    monitor->open_strip_chart(menu_def->_thread_index, 
+			      menu_def->_collector_index,
+			      menu_def->_show_level);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GtkStatsChartMenu::remove_menu_child
+//       Access: Private, Static
+//  Description: Removes a previous menu child from the menu.
+////////////////////////////////////////////////////////////////////
+void GtkStatsChartMenu::
+remove_menu_child(GtkWidget *widget, gpointer data) {
+  GtkWidget *menu = (GtkWidget *)data;
+  gtk_container_remove(GTK_CONTAINER(menu), widget);
+}

+ 8 - 5
pandatool/src/gtk-stats/gtkStatsChartMenu.h

@@ -21,7 +21,7 @@
 
 #include "pandatoolbase.h"
 
-#include <windows.h>
+#include <gtk/gtk.h>
 
 class GtkStatsMonitor;
 class PStatView;
@@ -37,21 +37,24 @@ public:
   GtkStatsChartMenu(GtkStatsMonitor *monitor, int thread_index);
   ~GtkStatsChartMenu();
 
-  HMENU get_menu_handle();
-  void add_to_menu_bar(HMENU menu_bar, int before_menu_id);
+  GtkWidget *get_menu_widget();
+  void add_to_menu_bar(GtkWidget *menu_bar, int before_menu_id);
 
   void check_update();
   void do_update();
 
 private:
-  void add_view(HMENU parent_menu, const PStatViewLevel *view_level,
+  void add_view(GtkWidget *parent_menu, const PStatViewLevel *view_level,
                 bool show_level);
 
+  static void handle_menu(gpointer data);
+  static void remove_menu_child(GtkWidget *widget, gpointer data);
+
   GtkStatsMonitor *_monitor;
   int _thread_index;
 
   int _last_level_index;
-  HMENU _menu;
+  GtkWidget *_menu;
 };
 
 #endif

+ 2 - 1
pandatool/src/gtk-stats/gtkStatsMonitor.I

@@ -26,7 +26,8 @@ GtkStatsMonitor::MenuDef::
 MenuDef(int thread_index, int collector_index, bool show_level) :
   _thread_index(thread_index),
   _collector_index(collector_index),
-  _show_level(show_level)
+  _show_level(show_level),
+  _monitor(NULL)
 {
 }
 

+ 20 - 64
pandatool/src/gtk-stats/gtkStatsMonitor.cxx

@@ -20,10 +20,8 @@
 #include "gtkStats.h"
 #include "gtkStatsServer.h"
 #include "gtkStatsStripChart.h"
-/*
-#include "gtkStatsPianoRoll.h"
 #include "gtkStatsChartMenu.h"
-*/
+//#include "gtkStatsPianoRoll.h"
 #include "gtkStatsMenuId.h"
 #include "pStatGraph.h"
 #include "pStatCollectorDef.h"
@@ -77,13 +75,11 @@ GtkStatsMonitor::
   }
   _graphs.clear();
 
-  /*
   ChartMenus::iterator mi;
   for (mi = _chart_menus.begin(); mi != _chart_menus.end(); ++mi) {
     delete (*mi);
   }
   _chart_menus.clear();
-  */
 
   if (_window != NULL) {
     gtk_widget_destroy(_window);
@@ -193,13 +189,11 @@ new_collector(int collector_index) {
     graph->new_collector(collector_index);
   }
 
-  /*
   // We might need to update our menus.
   ChartMenus::iterator mi;
   for (mi = _chart_menus.begin(); mi != _chart_menus.end(); ++mi) {
     (*mi)->do_update();
   }
-  */
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -215,12 +209,10 @@ new_collector(int collector_index) {
 ////////////////////////////////////////////////////////////////////
 void GtkStatsMonitor::
 new_thread(int thread_index) {
-  /*
   GtkStatsChartMenu *chart_menu = new GtkStatsChartMenu(this, thread_index);
-  chart_menu->add_to_menu_bar(_menu_bar, MI_frame_rate_label);
+  GtkWidget *menu_bar = gtk_item_factory_get_widget(_item_factory, "<PStats>");
+  chart_menu->add_to_menu_bar(menu_bar, MI_frame_rate_label);
   _chart_menus.push_back(chart_menu);
-  DrawMenuBar(_window);
-  */
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -269,13 +261,13 @@ lost_connection() {
 ////////////////////////////////////////////////////////////////////
 void GtkStatsMonitor::
 idle() {
-  /*
   // Check if any of our chart menus need updating.
   ChartMenus::iterator mi;
   for (mi = _chart_menus.begin(); mi != _chart_menus.end(); ++mi) {
     (*mi)->check_update();
   }
 
+  /*
   // Update the frame rate label from the main thread (thread 0).
   const PStatThreadData *thread_data = get_client_data()->get_thread_data(0);
   float frame_rate = thread_data->get_frame_rate();
@@ -363,43 +355,21 @@ open_piano_roll(int thread_index) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GtkStatsMonitor::lookup_menu
+//     Function: GtkStatsMonitor::add_menu
 //       Access: Public
-//  Description: Returns the MenuDef properties associated with the
-//               indicated menu ID.  This specifies what we expect to
-//               do when the given menu has been selected.
-////////////////////////////////////////////////////////////////////
-const GtkStatsMonitor::MenuDef &GtkStatsMonitor::
-lookup_menu(int menu_id) const {
-  static MenuDef invalid(0, 0, false);
-  int menu_index = menu_id - MI_new_chart;
-  nassertr(menu_index >= 0 && menu_index < (int)_menu_by_id.size(), invalid);
-  return _menu_by_id[menu_index];
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GtkStatsMonitor::get_menu_id
-//       Access: Public
-//  Description: Returns the menu ID that is reserved for the
-//               indicated MenuDef properties.  If this is the first
-//               time these particular properties have been requested,
-//               a new menu ID is returned; otherwise, the existing
-//               menu ID is returned.
-////////////////////////////////////////////////////////////////////
-int GtkStatsMonitor::
-get_menu_id(const MenuDef &menu_def) {
-  MenuByDef::iterator mi;
-  mi = _menu_by_def.find(menu_def);
-  if (mi != _menu_by_def.end()) {
-    return (*mi).second;
+//  Description: Adds a new MenuDef to the monitor, or returns an
+//               existing one if there is already one just like it.
+////////////////////////////////////////////////////////////////////
+const GtkStatsMonitor::MenuDef *GtkStatsMonitor::
+add_menu(const MenuDef &menu_def) {
+  pair<Menus::iterator, bool> result = _menus.insert(menu_def);
+  Menus::iterator mi = result.first;
+  const GtkStatsMonitor::MenuDef &new_menu_def = (*mi);
+  if (result.second) {
+    // A new MenuDef was inserted.
+    ((GtkStatsMonitor::MenuDef &)new_menu_def)._monitor = this;
   }
-
-  // Slot a new id.
-  int menu_id = (int)_menu_by_id.size() + MI_new_chart;
-  _menu_by_id.push_back(menu_def);
-  _menu_by_def[menu_def] = menu_id;
-
-  return menu_id;
+  return &new_menu_def;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -514,19 +484,17 @@ create_window() {
   gtk_item_factory_create_items(_item_factory, num_menu_entries, menu_entries,
 				this);
   gtk_window_add_accel_group(GTK_WINDOW(_window), accel_group);
-  GtkWidget *menubar = gtk_item_factory_get_widget(_item_factory, "<PStats>");
+  GtkWidget *menu_bar = gtk_item_factory_get_widget(_item_factory, "<PStats>");
 
-    /*
   ChartMenus::iterator mi;
   for (mi = _chart_menus.begin(); mi != _chart_menus.end(); ++mi) {
-    (*mi)->add_to_menu_bar(_menu_bar, MI_frame_rate_label);
+    (*mi)->add_to_menu_bar(menu_bar, MI_frame_rate_label);
   }
-  */
 
   // Pack the menu into the window.
   GtkWidget *main_vbox = gtk_vbox_new(FALSE, 1);
   gtk_container_add(GTK_CONTAINER(_window), main_vbox);
-  gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
+  gtk_box_pack_start(GTK_BOX(main_vbox), menu_bar, FALSE, TRUE, 0);
 
   gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item(_item_factory, "/Speed/3")),
 				 TRUE);
@@ -633,17 +601,5 @@ handle_menu_command(gpointer callback_data, guint menu_id, GtkWidget *widget) {
   case MI_pause:
     self->set_pause(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)));
     break;
-
-  default:
-    if (menu_id >= MI_new_chart) {
-      const MenuDef &menu_def = self->lookup_menu(menu_id);
-      if (menu_def._collector_index < 0) {
-        self->open_piano_roll(menu_def._thread_index);
-      } else {
-        self->open_strip_chart(menu_def._thread_index, 
-			       menu_def._collector_index,
-			       menu_def._show_level);
-      }
-    }
   }
 }

+ 4 - 6
pandatool/src/gtk-stats/gtkStatsMonitor.h

@@ -48,6 +48,7 @@ public:
     int _thread_index;
     int _collector_index;
     bool _show_level;
+    GtkStatsMonitor *_monitor;
   };
 
   GtkStatsMonitor(GtkStatsServer *server);
@@ -72,8 +73,7 @@ public:
   void open_strip_chart(int thread_index, int collector_index, bool show_level);
   void open_piano_roll(int thread_index);
 
-  const MenuDef &lookup_menu(int menu_id) const;
-  int get_menu_id(const MenuDef &menu_def);
+  const MenuDef *add_menu(const MenuDef &menu_def);
 
   void set_time_units(int unit_mask);
   void set_scroll_speed(float scroll_speed);
@@ -97,10 +97,8 @@ private:
   typedef pvector<GtkStatsChartMenu *> ChartMenus;
   ChartMenus _chart_menus;
 
-  typedef pvector<MenuDef> MenuById;
-  typedef pmap<MenuDef, int> MenuByDef;
-  MenuById _menu_by_id;
-  MenuByDef _menu_by_def;
+  typedef pset<MenuDef> Menus;
+  Menus _menus;
 
   GtkWidget *_window;
   GtkItemFactory *_item_factory;