diff --git a/pandatool/src/gtk-stats/gtkStatsFlameGraph.cxx b/pandatool/src/gtk-stats/gtkStatsFlameGraph.cxx index 30bbd44751..ea20558b9b 100644 --- a/pandatool/src/gtk-stats/gtkStatsFlameGraph.cxx +++ b/pandatool/src/gtk-stats/gtkStatsFlameGraph.cxx @@ -161,7 +161,7 @@ set_time_units(int unit_mask) { */ void GtkStatsFlameGraph:: on_click_label(int collector_index) { - set_collector_index(collector_index); + push_collector_index(collector_index); } /** @@ -440,7 +440,7 @@ handle_button_press(int graph_x, int graph_y, bool double_click, int button) { g_signal_connect(G_OBJECT(menu_item), "activate", G_CALLBACK(+[] (GtkWidget *widget, gpointer data) { GtkStatsFlameGraph *self = (GtkStatsFlameGraph *)data; - self->set_collector_index(self->_popup_index); + self->push_collector_index(self->_popup_index); }), this); } @@ -508,7 +508,13 @@ handle_button_press(int graph_x, int graph_y, bool double_click, int button) { else if (double_click && button == 1) { // Double-clicking on a color bar in the graph will zoom the graph into // that collector. - set_collector_index(collector_index); + if (collector_index >= 0) { + push_collector_index(collector_index); + } else { + // Double-clicking the background goes to the top. + clear_history(); + set_collector_index(-1); + } return TRUE; } } @@ -772,19 +778,29 @@ key_press_callback(GtkWidget *widget, GdkEventKey *event, gpointer data) { bool changed = false; switch (event->keyval) { case GDK_KEY_Left: - changed = self->prev_frame(); + if (event->state & GDK_MOD1_MASK) { + changed = self->pop_collector_index(); + } else { + changed = self->prev_frame(); + } break; case GDK_KEY_Right: - changed = self->next_frame(); + if ((event->state & GDK_MOD1_MASK) == 0) { + changed = self->next_frame(); + } break; case GDK_KEY_Home: - changed = self->first_frame(); + if ((event->state & GDK_MOD1_MASK) == 0) { + changed = self->first_frame(); + } break; case GDK_KEY_End: - changed = self->last_frame(); + if ((event->state & GDK_MOD1_MASK) == 0) { + changed = self->last_frame(); + } break; } diff --git a/pandatool/src/mac-stats/macStatsFlameGraph.h b/pandatool/src/mac-stats/macStatsFlameGraph.h index 62c7f27472..a678e887ba 100644 --- a/pandatool/src/mac-stats/macStatsFlameGraph.h +++ b/pandatool/src/mac-stats/macStatsFlameGraph.h @@ -84,8 +84,6 @@ private: NSToolbarItem *_total_item; MacStatsChartMenuDelegate *_menu_delegate; - - std::vector _back_stack; }; #endif diff --git a/pandatool/src/mac-stats/macStatsFlameGraph.mm b/pandatool/src/mac-stats/macStatsFlameGraph.mm index b241b401f8..003629d474 100644 --- a/pandatool/src/mac-stats/macStatsFlameGraph.mm +++ b/pandatool/src/mac-stats/macStatsFlameGraph.mm @@ -177,11 +177,10 @@ void MacStatsFlameGraph:: on_click_label(int collector_index) { int current = get_collector_index(); if (collector_index != current) { - if (_back_stack.empty()) { + if (get_history_depth() == 0) { _graph_view_controller.backToolbarItemVisible = YES; } - _back_stack.push_back(current); - set_collector_index(collector_index); + push_collector_index(collector_index); std::string window_title = get_title_text(); if (!is_title_unknown()) { @@ -589,11 +588,12 @@ handle_button_press(int graph_x, int graph_y, bool double_click, int button) { if (collector_index >= 0) { on_click_label(collector_index); } else { - if (!_back_stack.empty()) { - _back_stack.clear(); + if (get_history_depth() > 0) { + clear_history(); _graph_view_controller.backToolbarItemVisible = NO; } set_collector_index(-1); + std::string window_title = get_title_text(); if (!is_title_unknown()) { _window.title = [NSString stringWithUTF8String:window_title.c_str()]; @@ -726,12 +726,8 @@ handle_draw_graph(CGContextRef ctx, NSRect rect) { */ void MacStatsFlameGraph:: handle_back() { - if (!_back_stack.empty()) { - int collector_index = _back_stack.back(); - _back_stack.pop_back(); - set_collector_index(collector_index); - - if (_back_stack.empty()) { + if (pop_collector_index()) { + if (get_history_depth() == 0) { _graph_view_controller.backToolbarItemVisible = NO; } diff --git a/pandatool/src/pstatserver/pStatFlameGraph.I b/pandatool/src/pstatserver/pStatFlameGraph.I index b2363d5a4f..e99afd04af 100644 --- a/pandatool/src/pstatserver/pStatFlameGraph.I +++ b/pandatool/src/pstatserver/pStatFlameGraph.I @@ -27,6 +27,22 @@ get_collector_index() const { return _collector_index; } +/** + * Clears the history stack. + */ +INLINE void PStatFlameGraph:: +clear_history() { + _history.clear(); +} + +/** + * Returns the depth of the history stack. + */ +INLINE size_t PStatFlameGraph:: +get_history_depth() const { + return _history.size(); +} + /** * Returns the particular frame number whose data this flame graph reflects. * Returns -1 if we're looking at a moving average instead. diff --git a/pandatool/src/pstatserver/pStatFlameGraph.cxx b/pandatool/src/pstatserver/pStatFlameGraph.cxx index 48039d992b..9343682955 100644 --- a/pandatool/src/pstatserver/pStatFlameGraph.cxx +++ b/pandatool/src/pstatserver/pStatFlameGraph.cxx @@ -98,6 +98,8 @@ update() { /** * Changes the collector represented by this flame graph. This may force a * redraw. + * + * Leaves the history stack untouched. */ void PStatFlameGraph:: set_collector_index(int collector_index) { @@ -127,6 +129,32 @@ set_collector_index(int collector_index) { } } +/** + * Goes to a different collector, but remembers the previous collector. + */ +void PStatFlameGraph:: +push_collector_index(int collector_index) { + if (_collector_index != collector_index) { + _history.push_back(_collector_index); + set_collector_index(collector_index); + } +} + +/** + * Goes to the previous visited collector. Returns true if the history stack + * was non-empty. + */ +bool PStatFlameGraph:: +pop_collector_index() { + if (!_history.empty()) { + int collector_index = _history.back(); + _history.pop_back(); + set_collector_index(collector_index); + return true; + } + return false; +} + /** * Changes the frame number shown by this flame graph. This may force a redraw. */ diff --git a/pandatool/src/pstatserver/pStatFlameGraph.h b/pandatool/src/pstatserver/pStatFlameGraph.h index 25698a935b..5e742383b2 100644 --- a/pandatool/src/pstatserver/pStatFlameGraph.h +++ b/pandatool/src/pstatserver/pStatFlameGraph.h @@ -45,6 +45,10 @@ public: INLINE int get_thread_index() const; INLINE int get_collector_index() const; void set_collector_index(int collector_index); + void push_collector_index(int collector_index); + bool pop_collector_index(); + INLINE void clear_history(); + INLINE size_t get_history_depth() const; INLINE int get_frame_number() const; void set_frame_number(int collector_index); @@ -137,6 +141,8 @@ private: double _time_width; int _current_frame; bool _title_unknown; + + std::vector _history; }; #include "pStatFlameGraph.I"