parent
71e2b7fff6
commit
c48721493a
|
|
@ -226,7 +226,7 @@ add_view(GtkWidget *parent_menu, const PStatViewLevel *view_level,
|
|||
}
|
||||
else if (menu_item != nullptr && menu == nullptr) {
|
||||
// Unhook the signal handler, we are creating a submenu.
|
||||
GtkStatsMonitor::MenuDef smd(_thread_index, collector, GtkStatsMonitor::CT_strip_chart, show_level);
|
||||
GtkStatsMonitor::MenuDef smd(GtkStatsMonitor::CT_strip_chart, _thread_index, collector, -1, show_level);
|
||||
const GtkStatsMonitor::MenuDef *menu_def = _monitor->add_menu(smd);
|
||||
|
||||
g_signal_handlers_disconnect_by_data(G_OBJECT(menu_item), (void *)menu_def);
|
||||
|
|
@ -277,7 +277,7 @@ add_view(GtkWidget *parent_menu, const PStatViewLevel *view_level,
|
|||
GtkWidget *GtkStatsChartMenu::
|
||||
make_menu_item(const char *label, int collector_index, ChartType chart_type,
|
||||
bool show_level) {
|
||||
GtkStatsMonitor::MenuDef smd(_thread_index, collector_index, chart_type, show_level);
|
||||
GtkStatsMonitor::MenuDef smd(chart_type, _thread_index, collector_index, -1, show_level);
|
||||
const GtkStatsMonitor::MenuDef *menu_def = _monitor->add_menu(smd);
|
||||
|
||||
GtkWidget *menu_item = gtk_menu_item_new_with_label(label);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class GtkStatsLabel;
|
|||
class GtkStatsFlameGraph final : public PStatFlameGraph, public GtkStatsGraph {
|
||||
public:
|
||||
GtkStatsFlameGraph(GtkStatsMonitor *monitor, int thread_index,
|
||||
int collector_index=-1);
|
||||
int collector_index=-1, int frame_number=-1);
|
||||
virtual ~GtkStatsFlameGraph();
|
||||
|
||||
virtual void new_collector(int collector_index);
|
||||
|
|
@ -76,6 +76,8 @@ private:
|
|||
|
||||
static void toggled_callback(GtkToggleButton *button, gpointer data);
|
||||
static gboolean draw_callback(GtkWidget *widget, cairo_t *cr, gpointer data);
|
||||
static gboolean scroll_callback(GtkWidget *widget, GdkEventScroll *event, gpointer data);
|
||||
static gboolean key_press_callback(GtkWidget *widget, GdkEventKey *event, gpointer data);
|
||||
|
||||
private:
|
||||
std::string _net_value_text;
|
||||
|
|
|
|||
|
|
@ -15,10 +15,12 @@
|
|||
*
|
||||
*/
|
||||
INLINE GtkStatsMonitor::MenuDef::
|
||||
MenuDef(int thread_index, int collector_index, ChartType chart_type, bool show_level) :
|
||||
MenuDef(ChartType chart_type, int thread_index, int collector_index,
|
||||
int frame_number, bool show_level) :
|
||||
_chart_type(chart_type),
|
||||
_thread_index(thread_index),
|
||||
_collector_index(collector_index),
|
||||
_chart_type(chart_type),
|
||||
_frame_number(frame_number),
|
||||
_show_level(show_level),
|
||||
_monitor(nullptr)
|
||||
{
|
||||
|
|
@ -29,14 +31,17 @@ MenuDef(int thread_index, int collector_index, ChartType chart_type, bool show_l
|
|||
*/
|
||||
INLINE bool GtkStatsMonitor::MenuDef::
|
||||
operator < (const MenuDef &other) const {
|
||||
if (_chart_type != other._chart_type) {
|
||||
return _chart_type < other._chart_type;
|
||||
}
|
||||
if (_thread_index != other._thread_index) {
|
||||
return _thread_index < other._thread_index;
|
||||
}
|
||||
if (_collector_index != other._collector_index) {
|
||||
return _collector_index < other._collector_index;
|
||||
}
|
||||
if (_chart_type != other._chart_type) {
|
||||
return _chart_type < other._chart_type;
|
||||
if (_frame_number != other._frame_number) {
|
||||
return _frame_number < other._frame_number;
|
||||
}
|
||||
return (int)_show_level < (int)other._show_level;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -316,8 +316,8 @@ open_timeline() {
|
|||
* Opens a new flame graph showing the indicated data.
|
||||
*/
|
||||
PStatGraph *GtkStatsMonitor::
|
||||
open_flame_graph(int thread_index, int collector_index) {
|
||||
GtkStatsFlameGraph *graph = new GtkStatsFlameGraph(this, thread_index, collector_index);
|
||||
open_flame_graph(int thread_index, int collector_index, int frame_number) {
|
||||
GtkStatsFlameGraph *graph = new GtkStatsFlameGraph(this, thread_index, collector_index, frame_number);
|
||||
add_graph(graph);
|
||||
return graph;
|
||||
}
|
||||
|
|
@ -734,7 +734,7 @@ status_bar_button_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
|
|||
const PStatViewLevel *child_level = view_level->get_child(c);
|
||||
|
||||
int child_collector = child_level->get_collector();
|
||||
const MenuDef *menu_def = monitor->add_menu({0, child_collector, CT_strip_chart, true});
|
||||
const MenuDef *menu_def = monitor->add_menu({CT_strip_chart, 0, child_collector, -1, true});
|
||||
|
||||
double value = child_level->get_net_value();
|
||||
|
||||
|
|
@ -787,7 +787,8 @@ menu_activate(GtkWidget *widget, gpointer data) {
|
|||
|
||||
case CT_flame_graph:
|
||||
monitor->open_flame_graph(menu_def._thread_index,
|
||||
menu_def._collector_index);
|
||||
menu_def._collector_index,
|
||||
menu_def._frame_number);
|
||||
break;
|
||||
|
||||
case CT_piano_roll:
|
||||
|
|
@ -853,7 +854,7 @@ handle_status_bar_popup(int item) {
|
|||
const PStatViewLevel *child_level = view_level->get_child(c);
|
||||
|
||||
int child_collector = child_level->get_collector();
|
||||
const MenuDef *menu_def = add_menu({0, child_collector, CT_strip_chart, true});
|
||||
const MenuDef *menu_def = add_menu({CT_strip_chart, 0, child_collector, -1, true});
|
||||
|
||||
double value = child_level->get_net_value();
|
||||
|
||||
|
|
|
|||
|
|
@ -46,13 +46,14 @@ public:
|
|||
|
||||
class MenuDef {
|
||||
public:
|
||||
INLINE MenuDef(int thread_index, int collector_index,
|
||||
ChartType chart_type, bool show_level = false);
|
||||
INLINE MenuDef(ChartType chart_type, int thread_index, int collector_index,
|
||||
int frame_number = -1, bool show_level = false);
|
||||
INLINE bool operator < (const MenuDef &other) const;
|
||||
|
||||
ChartType _chart_type;
|
||||
int _thread_index;
|
||||
int _collector_index;
|
||||
ChartType _chart_type;
|
||||
int _frame_number;
|
||||
bool _show_level;
|
||||
GtkStatsMonitor *_monitor;
|
||||
};
|
||||
|
|
@ -84,7 +85,7 @@ public:
|
|||
|
||||
PStatGraph *open_timeline();
|
||||
PStatGraph *open_strip_chart(int thread_index, int collector_index, bool show_level);
|
||||
PStatGraph *open_flame_graph(int thread_index, int collector_index = -1);
|
||||
PStatGraph *open_flame_graph(int thread_index, int collector_index = -1, int frame_number = -1);
|
||||
PStatGraph *open_piano_roll(int thread_index);
|
||||
|
||||
void choose_collector_color(int collector_index);
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ on_popup_label(int collector_index) {
|
|||
|
||||
{
|
||||
const GtkStatsMonitor::MenuDef *menu_def = GtkStatsGraph::_monitor->add_menu({
|
||||
_thread_index, collector_index, GtkStatsMonitor::CT_strip_chart, false,
|
||||
GtkStatsMonitor::CT_strip_chart, _thread_index, collector_index,
|
||||
});
|
||||
|
||||
GtkWidget *menu_item = gtk_menu_item_new_with_label("Open Strip Chart");
|
||||
|
|
@ -161,7 +161,7 @@ on_popup_label(int collector_index) {
|
|||
|
||||
{
|
||||
const GtkStatsMonitor::MenuDef *menu_def = GtkStatsGraph::_monitor->add_menu({
|
||||
_thread_index, collector_index, GtkStatsMonitor::CT_flame_graph,
|
||||
GtkStatsMonitor::CT_flame_graph, _thread_index, collector_index,
|
||||
});
|
||||
|
||||
GtkWidget *menu_item = gtk_menu_item_new_with_label("Open Flame Graph");
|
||||
|
|
@ -178,7 +178,7 @@ on_popup_label(int collector_index) {
|
|||
|
||||
{
|
||||
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...");
|
||||
|
|
@ -190,7 +190,7 @@ on_popup_label(int collector_index) {
|
|||
|
||||
{
|
||||
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");
|
||||
|
|
|
|||
|
|
@ -243,8 +243,8 @@ on_popup_label(int collector_index) {
|
|||
|
||||
{
|
||||
const GtkStatsMonitor::MenuDef *menu_def = GtkStatsGraph::_monitor->add_menu({
|
||||
_thread_index, collector_index,
|
||||
GtkStatsMonitor::CT_strip_chart, get_view().get_show_level(),
|
||||
GtkStatsMonitor::CT_strip_chart, _thread_index, collector_index, -1,
|
||||
get_view().get_show_level(),
|
||||
});
|
||||
|
||||
GtkWidget *menu_item = gtk_menu_item_new_with_label("Open Strip Chart");
|
||||
|
|
@ -256,7 +256,7 @@ on_popup_label(int collector_index) {
|
|||
|
||||
if (!get_view().get_show_level()) {
|
||||
const GtkStatsMonitor::MenuDef *menu_def = GtkStatsGraph::_monitor->add_menu({
|
||||
_thread_index, collector_index, GtkStatsMonitor::CT_flame_graph,
|
||||
GtkStatsMonitor::CT_flame_graph, _thread_index, collector_index,
|
||||
});
|
||||
|
||||
GtkWidget *menu_item = gtk_menu_item_new_with_label("Open Flame Graph");
|
||||
|
|
@ -273,7 +273,7 @@ on_popup_label(int collector_index) {
|
|||
|
||||
{
|
||||
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...");
|
||||
|
|
@ -285,7 +285,7 @@ on_popup_label(int collector_index) {
|
|||
|
||||
{
|
||||
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");
|
||||
|
|
|
|||
|
|
@ -409,8 +409,8 @@ handle_button_press(int graph_x, int graph_y, bool double_click, int button) {
|
|||
|
||||
{
|
||||
const GtkStatsMonitor::MenuDef *menu_def = GtkStatsGraph::_monitor->add_menu({
|
||||
GtkStatsMonitor::CT_strip_chart,
|
||||
bar._thread_index, bar._collector_index,
|
||||
GtkStatsMonitor::CT_strip_chart, false,
|
||||
});
|
||||
|
||||
GtkWidget *menu_item = gtk_menu_item_new_with_label("Open Strip Chart");
|
||||
|
|
@ -422,8 +422,8 @@ handle_button_press(int graph_x, int graph_y, bool double_click, int button) {
|
|||
|
||||
{
|
||||
const GtkStatsMonitor::MenuDef *menu_def = GtkStatsGraph::_monitor->add_menu({
|
||||
bar._thread_index, bar._collector_index,
|
||||
GtkStatsMonitor::CT_flame_graph,
|
||||
bar._thread_index, bar._collector_index, bar._frame_number,
|
||||
});
|
||||
|
||||
GtkWidget *menu_item = gtk_menu_item_new_with_label("Open Flame Graph");
|
||||
|
|
@ -435,7 +435,7 @@ handle_button_press(int graph_x, int graph_y, bool double_click, int button) {
|
|||
|
||||
{
|
||||
const GtkStatsMonitor::MenuDef *menu_def = GtkStatsGraph::_monitor->add_menu({
|
||||
bar._thread_index, -1, GtkStatsMonitor::CT_piano_roll,
|
||||
GtkStatsMonitor::CT_piano_roll, bar._thread_index, -1,
|
||||
});
|
||||
|
||||
GtkWidget *menu_item = gtk_menu_item_new_with_label("Open Piano Roll");
|
||||
|
|
@ -452,8 +452,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, bar._collector_index,
|
||||
GtkStatsMonitor::CT_choose_color,
|
||||
GtkStatsMonitor::CT_choose_color, -1, bar._collector_index,
|
||||
});
|
||||
|
||||
GtkWidget *menu_item = gtk_menu_item_new_with_label("Change Color...");
|
||||
|
|
@ -465,8 +464,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, bar._collector_index,
|
||||
GtkStatsMonitor::CT_reset_color,
|
||||
GtkStatsMonitor::CT_reset_color, -1, bar._collector_index,
|
||||
});
|
||||
|
||||
GtkWidget *menu_item = gtk_menu_item_new_with_label("Reset Color");
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
class MacStatsFlameGraph final : public PStatFlameGraph, public MacStatsGraph {
|
||||
public:
|
||||
MacStatsFlameGraph(MacStatsMonitor *monitor, int thread_index,
|
||||
int collector_index=-1);
|
||||
int collector_index=-1, int frame_number=-1);
|
||||
virtual ~MacStatsFlameGraph();
|
||||
|
||||
virtual void new_collector(int collector_index);
|
||||
|
|
@ -60,11 +60,14 @@ protected:
|
|||
virtual std::string get_graph_tooltip(int mouse_x, int mouse_y) const;
|
||||
virtual DragMode consider_drag_start(int graph_x, int graph_y);
|
||||
|
||||
virtual bool handle_key(int graph_x, int graph_y, bool pressed,
|
||||
UniChar c, unsigned short key_code);
|
||||
virtual void handle_button_press(int graph_x, int graph_y,
|
||||
bool double_click, int button);
|
||||
bool double_click, int button);
|
||||
virtual void handle_button_release(int graph_x, int graph_y);
|
||||
virtual void handle_motion(int graph_x, int graph_y);
|
||||
virtual void handle_leave();
|
||||
virtual void handle_wheel(int graph_x, int graph_y, double dx, double dy);
|
||||
virtual void handle_draw_graph(CGContextRef ctx, NSRect rect);
|
||||
virtual void handle_back();
|
||||
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ static const int default_flame_graph_height = 250;
|
|||
*/
|
||||
MacStatsFlameGraph::
|
||||
MacStatsFlameGraph(MacStatsMonitor *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),
|
||||
MacStatsGraph(monitor, [MacStatsFlameGraphViewController alloc])
|
||||
{
|
||||
// Used for popup menus.
|
||||
|
|
@ -538,6 +538,43 @@ consider_drag_start(int graph_x, int graph_y) {
|
|||
return DM_none;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
bool MacStatsFlameGraph::
|
||||
handle_key(int graph_x, int graph_y, bool pressed, UniChar c, unsigned short key_code) {
|
||||
bool changed = false;
|
||||
|
||||
if (pressed) {
|
||||
switch (c) {
|
||||
case NSLeftArrowFunctionKey:
|
||||
changed = prev_frame();
|
||||
break;
|
||||
|
||||
case NSRightArrowFunctionKey:
|
||||
changed = next_frame();
|
||||
break;
|
||||
|
||||
case NSHomeFunctionKey:
|
||||
changed = first_frame();
|
||||
break;
|
||||
|
||||
case NSEndFunctionKey:
|
||||
changed = last_frame();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
std::string window_title = get_title_text();
|
||||
if (!is_title_unknown()) {
|
||||
_window.title = [NSString stringWithUTF8String:window_title.c_str()];
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the mouse button is depressed within the graph window.
|
||||
*/
|
||||
|
|
@ -652,6 +689,21 @@ handle_leave() {
|
|||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void MacStatsFlameGraph::
|
||||
handle_wheel(int graph_x, int graph_y, double dx, double dy) {
|
||||
if (dx != 0.0) {
|
||||
if ((dx > 0.0) ? prev_frame() : next_frame()) {
|
||||
std::string window_title = get_title_text();
|
||||
if (!is_title_unknown()) {
|
||||
_window.title = [NSString stringWithUTF8String:window_title.c_str()];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills in the graph window.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -45,15 +45,13 @@
|
|||
}
|
||||
|
||||
- (void)keyDown:(NSEvent *)event {
|
||||
if (!event.isARepeat) {
|
||||
NSPoint pos = [self convertPoint:event.locationInWindow fromView:nil];
|
||||
UniChar c = 0;
|
||||
NSString *str = [event charactersIgnoringModifiers];
|
||||
if (str != nil && str.length == 1) {
|
||||
c = [str characterAtIndex:0];
|
||||
}
|
||||
_graph->handle_key(pos.x, pos.y, true, c, event.keyCode);
|
||||
NSPoint pos = [self convertPoint:event.locationInWindow fromView:nil];
|
||||
UniChar c = 0;
|
||||
NSString *str = [event charactersIgnoringModifiers];
|
||||
if (str != nil && str.length == 1) {
|
||||
c = [str characterAtIndex:0];
|
||||
}
|
||||
_graph->handle_key(pos.x, pos.y, true, c, event.keyCode);
|
||||
}
|
||||
|
||||
- (void)keyUp:(NSEvent *)event {
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ public:
|
|||
|
||||
PStatGraph *open_timeline();
|
||||
PStatGraph *open_strip_chart(int thread_index, int collector_index, bool show_level);
|
||||
PStatGraph *open_flame_graph(int thread_index, int collector_index = -1);
|
||||
PStatGraph *open_flame_graph(int thread_index, int collector_index = -1, int frame_number = -1);
|
||||
PStatGraph *open_piano_roll(int thread_index);
|
||||
|
||||
CGColorRef get_collector_color(int collector_index, bool highlight = false);
|
||||
|
|
|
|||
|
|
@ -312,9 +312,9 @@ open_timeline() {
|
|||
* Opens a new flame graph showing the indicated data.
|
||||
*/
|
||||
PStatGraph *MacStatsMonitor::
|
||||
open_flame_graph(int thread_index, int collector_index) {
|
||||
open_flame_graph(int thread_index, int collector_index, int frame_number) {
|
||||
MacStatsFlameGraph *graph =
|
||||
new MacStatsFlameGraph(this, thread_index, collector_index);
|
||||
new MacStatsFlameGraph(this, thread_index, collector_index, frame_number);
|
||||
add_graph(graph);
|
||||
return graph;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -819,7 +819,7 @@ handle_open_strip_chart() {
|
|||
void MacStatsTimeline::
|
||||
handle_open_flame_graph() {
|
||||
const ColorBar &bar = _popup_bar;
|
||||
MacStatsGraph::_monitor->open_flame_graph(bar._thread_index, bar._collector_index);
|
||||
MacStatsGraph::_monitor->open_flame_graph(bar._thread_index, bar._collector_index, bar._frame_number);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -27,6 +27,15 @@ get_collector_index() const {
|
|||
return _collector_index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the particular frame number whose data this flame graph reflects.
|
||||
* Returns -1 if we're looking at a moving average instead.
|
||||
*/
|
||||
INLINE int PStatFlameGraph::
|
||||
get_frame_number() const {
|
||||
return _frame_number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of total time the width of the horizontal axis
|
||||
* represents.
|
||||
|
|
|
|||
|
|
@ -25,12 +25,13 @@
|
|||
*
|
||||
*/
|
||||
PStatFlameGraph::
|
||||
PStatFlameGraph(PStatMonitor *monitor,
|
||||
int thread_index, int collector_index, int xsize, int ysize) :
|
||||
PStatFlameGraph(PStatMonitor *monitor, int thread_index, int collector_index,
|
||||
int frame_number, int xsize, int ysize) :
|
||||
PStatGraph(monitor, xsize, ysize),
|
||||
_thread_index(thread_index),
|
||||
_collector_index(collector_index),
|
||||
_orig_collector_index(collector_index)
|
||||
_orig_collector_index(collector_index),
|
||||
_frame_number(frame_number)
|
||||
{
|
||||
_average_mode = true;
|
||||
_average_cursor = 0;
|
||||
|
|
@ -73,11 +74,20 @@ update() {
|
|||
const PStatThreadData *thread_data =
|
||||
client_data->get_thread_data(_thread_index);
|
||||
if (!thread_data->is_empty()) {
|
||||
int frame_number = thread_data->get_latest_frame_number();
|
||||
if (frame_number != _current_frame) {
|
||||
_current_frame = frame_number;
|
||||
if (_frame_number >= 0) {
|
||||
if (thread_data->has_frame(_frame_number)) {
|
||||
if (_current_frame != _frame_number) {
|
||||
_current_frame = _frame_number;
|
||||
update_data();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int frame_number = thread_data->get_latest_frame_number();
|
||||
if (frame_number != _current_frame) {
|
||||
_current_frame = frame_number;
|
||||
|
||||
update_data();
|
||||
update_data();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -117,6 +127,142 @@ set_collector_index(int collector_index) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the frame number shown by this flame graph. This may force a redraw.
|
||||
*/
|
||||
void PStatFlameGraph::
|
||||
set_frame_number(int frame_number) {
|
||||
if (_frame_number != frame_number) {
|
||||
_frame_number = frame_number;
|
||||
_current_frame = frame_number;
|
||||
_title_unknown = true;
|
||||
_stack.clear();
|
||||
update_data();
|
||||
|
||||
if (_average_mode) {
|
||||
_stack.update_averages(_average_cursor);
|
||||
_time_width = _stack.get_net_value(true);
|
||||
if (_time_width == 0.0) {
|
||||
_time_width = 1.0 / pstats_target_frame_rate;
|
||||
}
|
||||
normal_guide_bars();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the frame number to the oldest available frame.
|
||||
*/
|
||||
bool PStatFlameGraph::
|
||||
first_frame() {
|
||||
const PStatClientData *client_data = _monitor->get_client_data();
|
||||
if (client_data == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const PStatThreadData *thread_data = client_data->get_thread_data(_thread_index);
|
||||
if (thread_data == nullptr || thread_data->is_empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int oldest = thread_data->get_oldest_frame_number();
|
||||
if (_frame_number != oldest && thread_data->has_frame(oldest)) {
|
||||
set_frame_number(oldest);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances to the next available frame. Returns true if the frame number was
|
||||
* changed after a call to this method.
|
||||
*/
|
||||
bool PStatFlameGraph::
|
||||
next_frame() {
|
||||
const PStatClientData *client_data = _monitor->get_client_data();
|
||||
if (client_data == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const PStatThreadData *thread_data = client_data->get_thread_data(_thread_index);
|
||||
if (thread_data == nullptr || thread_data->is_empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int latest = thread_data->get_latest_frame_number();
|
||||
if (_frame_number < 0 || _frame_number > latest) {
|
||||
set_frame_number(latest);
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = _frame_number + 1; i <= latest; ++i) {
|
||||
if (thread_data->has_frame(i)) {
|
||||
set_frame_number(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverts to the previous frame. Returns true if the frame number was changed
|
||||
* after a call to this method.
|
||||
*/
|
||||
bool PStatFlameGraph::
|
||||
prev_frame() {
|
||||
const PStatClientData *client_data = _monitor->get_client_data();
|
||||
if (client_data == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const PStatThreadData *thread_data = client_data->get_thread_data(_thread_index);
|
||||
if (thread_data == nullptr || thread_data->is_empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int oldest = thread_data->get_oldest_frame_number();
|
||||
|
||||
int i;
|
||||
if (_frame_number < 0) {
|
||||
i = thread_data->get_latest_frame_number();
|
||||
} else {
|
||||
i = _frame_number - 1;
|
||||
}
|
||||
while (i >= oldest) {
|
||||
if (thread_data->has_frame(i)) {
|
||||
set_frame_number(i);
|
||||
return true;
|
||||
}
|
||||
--i;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the frame number to the latest available frame.
|
||||
*/
|
||||
bool PStatFlameGraph::
|
||||
last_frame() {
|
||||
const PStatClientData *client_data = _monitor->get_client_data();
|
||||
if (client_data == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const PStatThreadData *thread_data = client_data->get_thread_data(_thread_index);
|
||||
if (thread_data == nullptr || thread_data->is_empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int latest = thread_data->get_latest_frame_number();
|
||||
if (_frame_number != latest && thread_data->has_frame(latest)) {
|
||||
set_frame_number(latest);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text suitable for the title label on the top line.
|
||||
*/
|
||||
|
|
@ -150,6 +296,10 @@ get_title_text() {
|
|||
_title_unknown = true;
|
||||
}
|
||||
|
||||
if (_frame_number >= 0) {
|
||||
text += " (frame " + format_string(_frame_number) + ")";
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class PStatFrameData;
|
|||
class PStatFlameGraph : public PStatGraph {
|
||||
public:
|
||||
PStatFlameGraph(PStatMonitor *monitor,
|
||||
int thread_index, int collector_index,
|
||||
int thread_index, int collector_index, int frame_number,
|
||||
int xsize, int ysize);
|
||||
virtual ~PStatFlameGraph();
|
||||
|
||||
|
|
@ -46,6 +46,13 @@ public:
|
|||
INLINE int get_collector_index() const;
|
||||
void set_collector_index(int collector_index);
|
||||
|
||||
INLINE int get_frame_number() const;
|
||||
void set_frame_number(int collector_index);
|
||||
bool first_frame();
|
||||
bool next_frame();
|
||||
bool prev_frame();
|
||||
bool last_frame();
|
||||
|
||||
INLINE double get_horizontal_scale() const;
|
||||
|
||||
INLINE void set_average_mode(bool average_mode);
|
||||
|
|
@ -123,6 +130,7 @@ private:
|
|||
int _thread_index;
|
||||
int _collector_index;
|
||||
int _orig_collector_index;
|
||||
int _frame_number;
|
||||
bool _average_mode;
|
||||
size_t _average_cursor;
|
||||
|
||||
|
|
|
|||
|
|
@ -654,7 +654,7 @@ open_strip_chart(int thread_index, int collector_index, bool show_level) {
|
|||
* Opens a new flame graph showing the indicated data.
|
||||
*/
|
||||
PStatGraph *PStatMonitor::
|
||||
open_flame_graph(int thread_index, int collector_index) {
|
||||
open_flame_graph(int thread_index, int collector_index, int frame_number) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ public:
|
|||
|
||||
virtual PStatGraph *open_timeline();
|
||||
virtual PStatGraph *open_strip_chart(int thread_index, int collector_index, bool show_level);
|
||||
virtual PStatGraph *open_flame_graph(int thread_index, int collector_index = -1);
|
||||
virtual PStatGraph *open_flame_graph(int thread_index, int collector_index = -1, int frame_number = -1);
|
||||
virtual PStatGraph *open_piano_roll(int thread_index);
|
||||
|
||||
void write_datagram(Datagram &dg) const;
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ const char * const WinStatsFlameGraph::_window_class_name = "flame";
|
|||
*/
|
||||
WinStatsFlameGraph::
|
||||
WinStatsFlameGraph(WinStatsMonitor *monitor, int thread_index,
|
||||
int collector_index) :
|
||||
int collector_index, int frame_number) :
|
||||
PStatFlameGraph(monitor,
|
||||
thread_index, collector_index,
|
||||
thread_index, collector_index, frame_number,
|
||||
monitor->get_pixel_scale() * default_flame_graph_width / 4,
|
||||
monitor->get_pixel_scale() * default_flame_graph_height / 4),
|
||||
WinStatsGraph(monitor)
|
||||
|
|
@ -349,6 +349,7 @@ LONG WinStatsFlameGraph::
|
|||
window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
switch (msg) {
|
||||
case WM_LBUTTONDOWN:
|
||||
SetFocus(_window);
|
||||
if (_potential_drag_mode == DM_new_guide_bar) {
|
||||
set_drag_mode(DM_new_guide_bar);
|
||||
SetCapture(_graph_window);
|
||||
|
|
@ -393,6 +394,31 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
}
|
||||
break;
|
||||
|
||||
case WM_KEYDOWN:
|
||||
{
|
||||
bool changed = false;
|
||||
switch (wparam) {
|
||||
case VK_LEFT:
|
||||
changed = prev_frame();
|
||||
break;
|
||||
case VK_RIGHT:
|
||||
changed = next_frame();
|
||||
break;
|
||||
case VK_HOME:
|
||||
changed = first_frame();
|
||||
break;
|
||||
case VK_END:
|
||||
changed = last_frame();
|
||||
break;
|
||||
}
|
||||
if (changed) {
|
||||
std::string window_title = get_title_text();
|
||||
SetWindowText(_window, window_title.c_str());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -407,6 +433,7 @@ LONG WinStatsFlameGraph::
|
|||
graph_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
switch (msg) {
|
||||
case WM_LBUTTONDOWN:
|
||||
SetFocus(_window);
|
||||
if (_potential_drag_mode == DM_guide_bar && _drag_guide_bar >= 0) {
|
||||
set_drag_mode(DM_guide_bar);
|
||||
int16_t x = LOWORD(lparam);
|
||||
|
|
@ -518,6 +545,19 @@ graph_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
}
|
||||
break;
|
||||
|
||||
case WM_MOUSEHWHEEL:
|
||||
{
|
||||
int delta = GET_WHEEL_DELTA_WPARAM(wparam);
|
||||
if (delta != 0) {
|
||||
if (delta > 0 ? next_frame() : prev_frame()) {
|
||||
std::string window_title = get_title_text();
|
||||
SetWindowText(_window, window_title.c_str());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -760,6 +800,8 @@ create_window() {
|
|||
// Ensure that the window is on top of the stack.
|
||||
SetWindowPos(_window, HWND_TOP, 0, 0, 0, 0,
|
||||
SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
|
||||
|
||||
SetFocus(_window);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class WinStatsLabel;
|
|||
class WinStatsFlameGraph : public PStatFlameGraph, public WinStatsGraph {
|
||||
public:
|
||||
WinStatsFlameGraph(WinStatsMonitor *monitor, int thread_index,
|
||||
int collector_index=-1);
|
||||
int collector_index=-1, int frame_number=-1);
|
||||
virtual ~WinStatsFlameGraph();
|
||||
|
||||
virtual void new_data(int thread_index, int frame_number);
|
||||
|
|
|
|||
|
|
@ -332,8 +332,8 @@ open_strip_chart(int thread_index, int collector_index, bool show_level) {
|
|||
* Opens a new flame graph showing the indicated data.
|
||||
*/
|
||||
PStatGraph *WinStatsMonitor::
|
||||
open_flame_graph(int thread_index, int collector_index) {
|
||||
WinStatsFlameGraph *graph = new WinStatsFlameGraph(this, thread_index, collector_index);
|
||||
open_flame_graph(int thread_index, int collector_index, int frame_number) {
|
||||
WinStatsFlameGraph *graph = new WinStatsFlameGraph(this, thread_index, collector_index, frame_number);
|
||||
add_graph(graph);
|
||||
return graph;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ public:
|
|||
|
||||
PStatGraph *open_timeline();
|
||||
PStatGraph *open_strip_chart(int thread_index, int collector_index, bool show_level);
|
||||
PStatGraph *open_flame_graph(int thread_index, int collector_index = -1);
|
||||
PStatGraph *open_flame_graph(int thread_index, int collector_index = -1, int frame_number = -1);
|
||||
PStatGraph *open_piano_roll(int thread_index);
|
||||
|
||||
void choose_collector_color(int collector_index);
|
||||
|
|
|
|||
|
|
@ -463,7 +463,7 @@ graph_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
return 0;
|
||||
|
||||
case 103:
|
||||
WinStatsGraph::_monitor->open_flame_graph(_popup_bar._thread_index, _popup_bar._collector_index);
|
||||
WinStatsGraph::_monitor->open_flame_graph(_popup_bar._thread_index, _popup_bar._collector_index, _popup_bar._frame_number);
|
||||
return 0;
|
||||
|
||||
case 104:
|
||||
|
|
|
|||
Loading…
Reference in New Issue