15 #include "gtkStatsStripChart.h"
16 #include "gtkStatsMonitor.h"
17 #include "pStatCollectorDef.h"
18 #include "numeric_types.h"
20 static const int default_strip_chart_width = 400;
21 static const int default_strip_chart_height = 100;
30 int collector_index,
bool show_level) :
32 show_level ? monitor->get_level_view(collector_index, thread_index) : monitor->get_view(thread_index),
35 default_strip_chart_width,
36 default_strip_chart_height),
43 if (_unit_name.empty()) {
44 set_guide_bar_units(GBU_named);
46 set_guide_bar_units(GBU_named | GBU_show_units);
51 set_guide_bar_units(get_guide_bar_units() | GBU_show_units);
55 _top_hbox = gtk_hbox_new(FALSE, 0);
56 gtk_box_pack_start(GTK_BOX(_graph_vbox), _top_hbox,
59 _smooth_check_box = gtk_check_button_new_with_label(
"Smooth");
60 g_signal_connect(G_OBJECT(_smooth_check_box),
"toggled",
61 G_CALLBACK(toggled_callback),
this);
63 _total_label = gtk_label_new(
"");
64 gtk_box_pack_start(GTK_BOX(_top_hbox), _smooth_check_box,
66 gtk_box_pack_end(GTK_BOX(_top_hbox), _total_label,
71 _scale_area = gtk_drawing_area_new();
72 g_signal_connect(G_OBJECT(_scale_area),
"expose_event",
73 G_CALLBACK(expose_event_callback),
this);
74 gtk_box_pack_start(GTK_BOX(_graph_hbox), _scale_area,
76 gtk_widget_set_size_request(_scale_area, 40, 0);
79 gtk_widget_set_size_request(_graph_window, default_strip_chart_width,
80 default_strip_chart_height);
82 gtk_widget_show_all(_window);
83 gtk_widget_show(_window);
88 gtk_widget_set_size_request(_window, 0, 0);
99 ~GtkStatsStripChart() {
127 gtk_window_set_title(GTK_WINDOW(_window), window_title.c_str());
135 if (_net_value_text != text) {
136 _net_value_text = text;
137 gtk_label_set_text(GTK_LABEL(_total_label), _net_value_text.c_str());
149 PStatStripChart::force_redraw();
160 PStatStripChart::changed_size(graph_xsize, graph_ysize);
174 if ((old_unit_mask & (GBU_hz | GBU_ms)) != 0) {
175 unit_mask = unit_mask & (GBU_hz | GBU_ms);
176 unit_mask |= (old_unit_mask & GBU_show_units);
179 gtk_widget_queue_draw(_scale_area);
193 if (scroll_speed != 0.0f) {
205 if (collector_index < 0) {
218 if (def._parent_index == 0 &&
get_view().get_show_level()) {
241 gtk_widget_queue_draw(_graph_window);
242 gtk_widget_queue_draw(_scale_area);
250 void GtkStatsStripChart::
252 PStatStripChart::update_labels();
254 _label_stack.clear_labels();
256 _label_stack.add_label(GtkStatsGraph::_monitor,
this, _thread_index,
259 _labels_changed =
false;
267 void GtkStatsStripChart::
269 gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_white);
270 gdk_draw_rectangle(_pixmap, _pixmap_gc, TRUE, 0, 0,
281 void GtkStatsStripChart::
282 copy_region(
int start_x,
int end_x,
int dest_x) {
283 gdk_draw_drawable(_pixmap, _pixmap_gc, _pixmap,
284 start_x, 0, dest_x, 0,
289 _brush_origin += (dest_x - start_x);
292 GdkRectangle rect = {
295 gdk_window_invalidate_rect(_graph_window->window, &rect, FALSE);
305 void GtkStatsStripChart::
308 gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_white);
309 gdk_draw_rectangle(_pixmap, _pixmap_gc, TRUE, x, 0,
312 double overall_time = 0.0;
315 FrameData::const_iterator fi;
316 for (fi = fdata.begin(); fi != fdata.end(); ++fi) {
317 const ColorData &cd = (*fi);
318 overall_time += cd._net_value;
319 GdkGC *gc = get_collector_gc(cd._collector_index);
324 gdk_draw_rectangle(_pixmap, gc, TRUE, x, 0, w, y);
330 gdk_draw_rectangle(_pixmap, gc, TRUE, x, top_y, w, y - top_y);
340 void GtkStatsStripChart::
341 draw_empty(
int x,
int w) {
342 gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_white);
343 gdk_draw_rectangle(_pixmap, _pixmap_gc, TRUE, x, 0,
352 void GtkStatsStripChart::
354 gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_black);
355 gdk_draw_line(_pixmap, _pixmap_gc, x, 0, x,
get_ysize());
366 void GtkStatsStripChart::
367 end_draw(
int from_x,
int to_x) {
370 for (
int i = 0; i < num_guide_bars; i++) {
374 GdkRectangle rect = {
375 from_x, 0, to_x - from_x + 1,
get_ysize()
377 gdk_window_invalidate_rect(_graph_window->window, &rect, FALSE);
387 void GtkStatsStripChart::
388 additional_graph_window_paint() {
390 for (
int i = 0; i < num_user_guide_bars; i++) {
403 GtkStatsGraph::DragMode GtkStatsStripChart::
404 consider_drag_start(
int graph_x,
int graph_y) {
405 if (graph_x >= 0 && graph_x <
get_xsize()) {
406 if (graph_y >= 0 && graph_y <
get_ysize()) {
412 if (_drag_guide_bar >= 0) {
419 return DM_new_guide_bar;
423 return GtkStatsGraph::consider_drag_start(graph_x, graph_y);
433 void GtkStatsStripChart::
434 set_drag_mode(GtkStatsGraph::DragMode drag_mode) {
435 GtkStatsGraph::set_drag_mode(drag_mode);
437 switch (_drag_mode) {
448 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(_smooth_check_box));
460 gboolean GtkStatsStripChart::
461 handle_button_press(GtkWidget *widget,
int graph_x,
int graph_y,
470 if (_potential_drag_mode == DM_none) {
471 set_drag_mode(DM_scale);
476 }
else if (_potential_drag_mode == DM_guide_bar && _drag_guide_bar >= 0) {
477 set_drag_mode(DM_guide_bar);
478 _drag_start_y = graph_y;
483 return GtkStatsGraph::handle_button_press(widget, graph_x, graph_y,
493 gboolean GtkStatsStripChart::
494 handle_button_release(GtkWidget *widget,
int graph_x,
int graph_y) {
495 if (_drag_mode == DM_scale) {
496 set_drag_mode(DM_none);
498 return handle_motion(widget, graph_x, graph_y);
500 }
else if (_drag_mode == DM_guide_bar) {
501 if (graph_y < 0 || graph_y >=
get_ysize()) {
506 set_drag_mode(DM_none);
508 return handle_motion(widget, graph_x, graph_y);
511 return GtkStatsGraph::handle_button_release(widget, graph_x, graph_y);
520 gboolean GtkStatsStripChart::
521 handle_motion(GtkWidget *widget,
int graph_x,
int graph_y) {
522 if (_drag_mode == DM_none && _potential_drag_mode == DM_none) {
540 _label_stack.highlight_label(-1);
543 if (_drag_mode == DM_scale) {
544 double ratio = 1.0f - ((double)graph_y / (
double)
get_ysize());
550 }
else if (_drag_mode == DM_new_guide_bar) {
553 if (graph_y >= 0 && graph_y <
get_ysize()) {
554 set_drag_mode(DM_guide_bar);
559 }
else if (_drag_mode == DM_guide_bar) {
564 return GtkStatsGraph::handle_motion(widget, graph_x, graph_y);
573 void GtkStatsStripChart::
574 draw_guide_bar(GdkDrawable *surface,
int from_x,
int to_x,
580 switch (bar._style) {
582 gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_light_gray);
586 gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_user_guide_bar);
590 gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_dark_gray);
593 gdk_draw_line(surface, _pixmap_gc, from_x, y, to_x, y);
602 void GtkStatsStripChart::
603 draw_guide_labels() {
609 for (i = 0; i < num_guide_bars; i++) {
614 draw_guide_label(top_value, last_y);
618 for (i = 0; i < num_user_guide_bars; i++) {
631 int GtkStatsStripChart::
633 GdkGC *gc = gdk_gc_new(_scale_area->window);
635 switch (bar._style) {
637 gdk_gc_set_rgb_fg_color(gc, &rgb_light_gray);
641 gdk_gc_set_rgb_fg_color(gc, &rgb_user_guide_bar);
645 gdk_gc_set_rgb_fg_color(gc, &rgb_dark_gray);
650 const string &label = bar._label;
652 PangoLayout *layout = gtk_widget_create_pango_layout(_window, label.c_str());
654 pango_layout_get_pixel_size(layout, &width, &height);
656 if (bar._style != GBS_user) {
661 g_object_unref(layout);
672 gtk_widget_translate_coordinates(_graph_window, _scale_area,
676 int this_y = y - height / 2;
677 if (last_y < this_y || last_y > this_y + height) {
678 gdk_draw_layout(_scale_area->window, gc, 0, this_y, layout);
683 g_object_unref(layout);
693 void GtkStatsStripChart::
694 toggled_callback(GtkToggleButton *button, gpointer data) {
697 bool active = gtk_toggle_button_get_active(button);
698 self->set_average_mode(active);
706 gboolean GtkStatsStripChart::
707 expose_event_callback(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
709 self->draw_guide_labels();
void set_horizontal_scale(double time_width)
Changes the amount of time the width of the horizontal axis represents.
int height_to_pixel(double value) const
Converts a value (i.e.
double pixel_to_height(int y) const
Converts a vertical pixel offset to a value (a "height" in the strip chart).
bool is_title_unknown() const
Returns true if get_title_text() has never yet returned an answer, false if it has.
A window that draws a strip chart, given a view.
int get_ysize() const
Returns the height of the chart in pixels.
void set_guide_bar_units(int unit_mask)
Sets the units that are displayed for the guide bar labels.
int get_label_collector(int n) const
Returns the collector index associated with the nth label.
void move_user_guide_bar(int n, double height)
Adjusts the height of the nth user-defined guide bar.
The data associated with a particular client, but not with any one particular frame or thread: the li...
void set_vertical_scale(double value_height)
Changes the value the height of the vertical axis represents.
virtual void new_collector(int collector_index)
Called whenever a new Collector definition is received from the client.
This is an abstract class that presents the interface for drawing a basic strip-chart, showing the relative value over an interval of time for several different collectors, differentiated by bands of color.
bool has_collector(int index) const
Returns true if the indicated collector has been defined by the client already, false otherwise...
int get_num_guide_bars() const
Returns the number of horizontal guide bars that should be drawn, based on the indicated target frame...
int get_collector_under_pixel(int xpoint, int ypoint)
Return the collector index associated with the particular band of color at the indicated pixel locati...
This is our own Panda specialization on the default STL vector.
virtual void new_collector(int collector_index)
Called whenever a new Collector definition is received from the client.
void update()
Updates the chart with the latest data.
const PStatCollectorDef & get_collector_def(int index) const
Returns the nth collector definition.
const GuideBar & get_guide_bar(int n) const
Returns the nth horizontal guide bar.
int get_collector_index() const
Returns the particular collector whose data this strip chart reflects.
string get_title_text()
Returns the text suitable for the title label on the top line.
virtual void set_time_units(int unit_mask)
Called when the user selects a new time units from the monitor pulldown menu, this should adjust the ...
virtual void new_data(int thread_index, int frame_number)
Called as each frame's data is made available.
int find_user_guide_bar(double from_height, double to_height) const
Returns the index number of the first user guide bar found whose height is within the indicated range...
GuideBar get_user_guide_bar(int n) const
Returns the nth user-defined guide bar.
This is just an abstract base class to provide a common pointer type for the various kinds of graphs ...
int get_num_labels() const
Returns the number of labels to be drawn for this chart.
virtual void clicked_label(int collector_index)
Called when the user single-clicks on a label.
This class represents a connection to a PStatsClient and manages the data exchange with the client...
int get_xsize() const
Returns the width of the chart in pixels.
int get_guide_bar_units() const
Returns the units that are displayed for the guide bar labels.
const PStatClientData * get_client_data() const
Returns the client data associated with this monitor.
const string & get_guide_bar_unit_name() const
Returns the name of the units to be used for the guide bars if the units type is set to GBU_named | G...
void set_average_mode(bool average_mode)
Changes the average_mode flag.
void set_collector_index(int collector_index)
Changes the collector represented by this strip chart.
virtual void force_redraw()
Called when it is necessary to redraw the entire graph.
double get_vertical_scale() const
Returns total value the height of the vertical axis represents.
virtual void set_scroll_speed(double scroll_speed)
Called when the user selects a new scroll speed from the monitor pulldown menu, this should adjust th...
virtual void changed_graph_size(int graph_xsize, int graph_ysize)
Called when the user has resized the window, forcing a resize of the graph.
PStatView & get_view() const
Returns the View this chart represents.
int add_user_guide_bar(double height)
Creates a new user guide bar and returns its index number.
Defines the details about the Collectors: the name, the suggested color, etc.
static string format_number(double value)
Returns a string representing the value nicely formatted for its range.
void set_vertical_scale(double value_height)
Changes the value the height of the vertical axis represents.
int get_num_user_guide_bars() const
Returns the current number of user-defined guide bars.
void remove_user_guide_bar(int n)
Removes the user guide bar with the indicated index number.