|
|
@@ -24,13 +24,16 @@ static const int default_flame_graph_height = 150;
|
|
|
*/
|
|
|
GtkStatsFlameGraph::
|
|
|
GtkStatsFlameGraph(GtkStatsMonitor *monitor, int thread_index,
|
|
|
- int collector_index) :
|
|
|
- PStatFlameGraph(monitor, thread_index, collector_index, 0, 0),
|
|
|
+ int collector_index, int frame_number) :
|
|
|
+ PStatFlameGraph(monitor, thread_index, collector_index, frame_number, 0, 0),
|
|
|
GtkStatsGraph(monitor, false)
|
|
|
{
|
|
|
// Let's show the units on the guide bar labels. There's room.
|
|
|
set_guide_bar_units(get_guide_bar_units() | GBU_show_units);
|
|
|
|
|
|
+ std::string window_title = get_title_text();
|
|
|
+ gtk_window_set_title(GTK_WINDOW(_window), window_title.c_str());
|
|
|
+
|
|
|
// Put some stuff on top of the graph.
|
|
|
_top_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
|
|
gtk_box_pack_start(GTK_BOX(_graph_vbox), _top_hbox,
|
|
|
@@ -51,6 +54,13 @@ GtkStatsFlameGraph(GtkStatsMonitor *monitor, int thread_index,
|
|
|
gtk_box_pack_start(GTK_BOX(_top_hbox), _scale_area, TRUE, TRUE, 0);
|
|
|
gtk_box_pack_end(GTK_BOX(_top_hbox), _total_label, FALSE, FALSE, 0);
|
|
|
|
|
|
+ // Listen for mouse scroll and keyboard events.
|
|
|
+ gtk_widget_add_events(_window, GDK_SCROLL_MASK | GDK_KEY_PRESS_MASK);
|
|
|
+ g_signal_connect(G_OBJECT(_window), "scroll_event",
|
|
|
+ G_CALLBACK(scroll_callback), this);
|
|
|
+ g_signal_connect(G_OBJECT(_window), "key_press_event",
|
|
|
+ G_CALLBACK(key_press_callback), this);
|
|
|
+
|
|
|
gtk_widget_set_size_request(_graph_window,
|
|
|
default_flame_graph_width * monitor->get_resolution() / 96,
|
|
|
default_flame_graph_height * monitor->get_resolution() / 96);
|
|
|
@@ -284,6 +294,15 @@ draw_bar(int depth, int from_x, int to_x, int collector_index, int parent_index)
|
|
|
pango_layout_set_text(layout, def._name.c_str(), def._name.size());
|
|
|
}
|
|
|
}
|
|
|
+ else if (collector_index == 0 && get_frame_number() >= 0) {
|
|
|
+ char text[32];
|
|
|
+ sprintf(text, "Frame %d", get_frame_number());
|
|
|
+ pango_layout_set_text(layout, text, -1);
|
|
|
+ if (pango_layout_is_ellipsized(layout)) {
|
|
|
+ // Nope, it's too long, go back.
|
|
|
+ pango_layout_set_text(layout, def._name.c_str(), def._name.size());
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
int width, height;
|
|
|
@@ -429,8 +448,7 @@ handle_button_press(int graph_x, int graph_y, bool double_click, int button) {
|
|
|
|
|
|
{
|
|
|
const GtkStatsMonitor::MenuDef *menu_def = GtkStatsGraph::_monitor->add_menu({
|
|
|
- get_thread_index(), collector_index,
|
|
|
- GtkStatsMonitor::CT_strip_chart, false,
|
|
|
+ GtkStatsMonitor::CT_strip_chart, get_thread_index(), collector_index,
|
|
|
});
|
|
|
|
|
|
GtkWidget *menu_item = gtk_menu_item_new_with_label("Open Strip Chart");
|
|
|
@@ -442,8 +460,7 @@ handle_button_press(int graph_x, int graph_y, bool double_click, int button) {
|
|
|
|
|
|
{
|
|
|
const GtkStatsMonitor::MenuDef *menu_def = GtkStatsGraph::_monitor->add_menu({
|
|
|
- get_thread_index(), collector_index,
|
|
|
- GtkStatsMonitor::CT_flame_graph,
|
|
|
+ GtkStatsMonitor::CT_flame_graph, get_thread_index(), collector_index,
|
|
|
});
|
|
|
|
|
|
GtkWidget *menu_item = gtk_menu_item_new_with_label("Open Flame Graph");
|
|
|
@@ -460,8 +477,7 @@ handle_button_press(int graph_x, int graph_y, bool double_click, int button) {
|
|
|
|
|
|
{
|
|
|
const GtkStatsMonitor::MenuDef *menu_def = GtkStatsGraph::_monitor->add_menu({
|
|
|
- -1, collector_index,
|
|
|
- GtkStatsMonitor::CT_choose_color,
|
|
|
+ GtkStatsMonitor::CT_choose_color, -1, collector_index,
|
|
|
});
|
|
|
|
|
|
GtkWidget *menu_item = gtk_menu_item_new_with_label("Change Color...");
|
|
|
@@ -473,8 +489,7 @@ handle_button_press(int graph_x, int graph_y, bool double_click, int button) {
|
|
|
|
|
|
{
|
|
|
const GtkStatsMonitor::MenuDef *menu_def = GtkStatsGraph::_monitor->add_menu({
|
|
|
- -1, collector_index,
|
|
|
- GtkStatsMonitor::CT_reset_color,
|
|
|
+ GtkStatsMonitor::CT_reset_color, -1, collector_index,
|
|
|
});
|
|
|
|
|
|
GtkWidget *menu_item = gtk_menu_item_new_with_label("Reset Color");
|
|
|
@@ -721,3 +736,63 @@ draw_callback(GtkWidget *widget, cairo_t *cr, gpointer data) {
|
|
|
|
|
|
return TRUE;
|
|
|
}
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ */
|
|
|
+gboolean GtkStatsFlameGraph::
|
|
|
+scroll_callback(GtkWidget *widget, GdkEventScroll *event, gpointer data) {
|
|
|
+ GtkStatsFlameGraph *self = (GtkStatsFlameGraph *)data;
|
|
|
+ bool changed = false;
|
|
|
+ switch (event->direction) {
|
|
|
+ case GDK_SCROLL_LEFT:
|
|
|
+ changed = self->prev_frame();
|
|
|
+ break;
|
|
|
+
|
|
|
+ case GDK_SCROLL_RIGHT:
|
|
|
+ changed = self->next_frame();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (changed) {
|
|
|
+ std::string window_title = self->get_title_text();
|
|
|
+ gtk_window_set_title(GTK_WINDOW(self->_window), window_title.c_str());
|
|
|
+ return TRUE;
|
|
|
+ } else {
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ */
|
|
|
+gboolean GtkStatsFlameGraph::
|
|
|
+key_press_callback(GtkWidget *widget, GdkEventKey *event, gpointer data) {
|
|
|
+ GtkStatsFlameGraph *self = (GtkStatsFlameGraph *)data;
|
|
|
+ bool changed = false;
|
|
|
+ switch (event->keyval) {
|
|
|
+ case GDK_KEY_Left:
|
|
|
+ changed = self->prev_frame();
|
|
|
+ break;
|
|
|
+
|
|
|
+ case GDK_KEY_Right:
|
|
|
+ changed = self->next_frame();
|
|
|
+ break;
|
|
|
+
|
|
|
+ case GDK_KEY_Home:
|
|
|
+ changed = self->first_frame();
|
|
|
+ break;
|
|
|
+
|
|
|
+ case GDK_KEY_End:
|
|
|
+ changed = self->last_frame();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (changed) {
|
|
|
+ std::string window_title = self->get_title_text();
|
|
|
+ gtk_window_set_title(GTK_WINDOW(self->_window), window_title.c_str());
|
|
|
+ return TRUE;
|
|
|
+ } else {
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+}
|