19 static const int default_piano_roll_width = 400;
20 static const int default_piano_roll_height = 200;
28 default_piano_roll_width,
29 default_piano_roll_height),
33 set_guide_bar_units(get_guide_bar_units() | GBU_show_units);
37 _scale_area = gtk_drawing_area_new();
38 g_signal_connect(G_OBJECT(_scale_area),
"expose_event",
39 G_CALLBACK(expose_event_callback),
this);
40 gtk_box_pack_start(GTK_BOX(_graph_vbox), _scale_area,
42 gtk_widget_set_size_request(_scale_area, 0, 20);
45 gtk_widget_set_size_request(_graph_window, default_piano_roll_width,
46 default_piano_roll_height);
51 std::string window_title = thread_name +
" thread piano roll";
52 gtk_window_set_title(GTK_WINDOW(_window), window_title.c_str());
54 gtk_widget_show_all(_window);
55 gtk_widget_show(_window);
60 gtk_widget_set_size_request(_window, 0, 0);
69 ~GtkStatsPianoRoll() {
90 PStatPianoRoll::force_redraw();
98 PStatPianoRoll::changed_size(graph_xsize, graph_ysize);
108 int old_unit_mask = get_guide_bar_units();
109 if ((old_unit_mask & (GBU_hz | GBU_ms)) != 0) {
110 unit_mask = unit_mask & (GBU_hz | GBU_ms);
111 unit_mask |= (old_unit_mask & GBU_show_units);
112 set_guide_bar_units(unit_mask);
114 gtk_widget_queue_draw(_scale_area);
123 if (collector_index >= 0) {
124 GtkStatsGraph::_monitor->
open_strip_chart(_thread_index, collector_index,
false);
136 gtk_widget_queue_draw(_graph_window);
137 gtk_widget_queue_draw(_scale_area);
143 void GtkStatsPianoRoll::
145 gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_white);
146 gdk_draw_rectangle(_pixmap, _pixmap_gc, TRUE, 0, 0,
147 get_xsize(), get_ysize());
153 void GtkStatsPianoRoll::
158 int num_guide_bars = get_num_guide_bars();
159 for (
int i = 0; i < num_guide_bars; i++) {
160 draw_guide_bar(_pixmap, get_guide_bar(i));
167 void GtkStatsPianoRoll::
168 draw_bar(
int row,
int from_x,
int to_x) {
169 if (row >= 0 && row < _label_stack.get_num_labels()) {
170 int y = _label_stack.get_label_y(row, _graph_window);
171 int height = _label_stack.get_label_height(row);
173 int collector_index = get_label_collector(row);
174 GdkGC *gc = get_collector_gc(collector_index);
176 gdk_draw_rectangle(_pixmap, gc, TRUE,
177 from_x, y - height + 2,
178 to_x - from_x, height - 4);
186 void GtkStatsPianoRoll::
188 gtk_widget_queue_draw(_graph_window);
194 void GtkStatsPianoRoll::
196 if (_labels_changed) {
205 void GtkStatsPianoRoll::
206 additional_graph_window_paint() {
207 int num_user_guide_bars = get_num_user_guide_bars();
208 for (
int i = 0; i < num_user_guide_bars; i++) {
209 draw_guide_bar(_graph_window->window, get_user_guide_bar(i));
218 GtkStatsGraph::DragMode GtkStatsPianoRoll::
219 consider_drag_start(
int graph_x,
int graph_y) {
220 if (graph_y >= 0 && graph_y < get_ysize()) {
221 if (graph_x >= 0 && graph_x < get_xsize()) {
224 double from_height = pixel_to_height(x - 2);
225 double to_height = pixel_to_height(x + 2);
226 _drag_guide_bar = find_user_guide_bar(from_height, to_height);
227 if (_drag_guide_bar >= 0) {
234 return DM_new_guide_bar;
238 return GtkStatsGraph::consider_drag_start(graph_x, graph_y);
244 gboolean GtkStatsPianoRoll::
245 handle_button_press(GtkWidget *widget,
int graph_x,
int graph_y,
254 if (_potential_drag_mode == DM_none) {
255 set_drag_mode(DM_scale);
256 _drag_scale_start = pixel_to_height(graph_x);
260 }
else if (_potential_drag_mode == DM_guide_bar && _drag_guide_bar >= 0) {
261 set_drag_mode(DM_guide_bar);
262 _drag_start_x = graph_x;
267 return GtkStatsGraph::handle_button_press(widget, graph_x, graph_y,
274 gboolean GtkStatsPianoRoll::
275 handle_button_release(GtkWidget *widget,
int graph_x,
int graph_y) {
276 if (_drag_mode == DM_scale) {
277 set_drag_mode(DM_none);
279 return handle_motion(widget, graph_x, graph_y);
281 }
else if (_drag_mode == DM_guide_bar) {
282 if (graph_x < 0 || graph_x >= get_xsize()) {
283 remove_user_guide_bar(_drag_guide_bar);
285 move_user_guide_bar(_drag_guide_bar, pixel_to_height(graph_x));
287 set_drag_mode(DM_none);
289 return handle_motion(widget, graph_x, graph_y);
292 return GtkStatsGraph::handle_button_release(widget, graph_x, graph_y);
298 gboolean GtkStatsPianoRoll::
299 handle_motion(GtkWidget *widget,
int graph_x,
int graph_y) {
300 if (_drag_mode == DM_none && _potential_drag_mode == DM_none) {
302 _label_stack.highlight_label(get_collector_under_pixel(graph_x, graph_y));
318 _label_stack.highlight_label(-1);
321 if (_drag_mode == DM_scale) {
322 double ratio = (double)graph_x / (
double)get_xsize();
324 set_horizontal_scale(_drag_scale_start / ratio);
328 }
else if (_drag_mode == DM_new_guide_bar) {
331 if (graph_x >= 0 && graph_x < get_xsize()) {
332 set_drag_mode(DM_guide_bar);
333 _drag_guide_bar = add_user_guide_bar(pixel_to_height(graph_x));
337 }
else if (_drag_mode == DM_guide_bar) {
338 move_user_guide_bar(_drag_guide_bar, pixel_to_height(graph_x));
342 return GtkStatsGraph::handle_motion(widget, graph_x, graph_y);
349 int GtkStatsPianoRoll::
350 get_collector_under_pixel(
int xpoint,
int ypoint) {
351 if (_label_stack.get_num_labels() == 0) {
356 int height = _label_stack.get_label_height(0);
357 int row = (get_ysize() - ypoint) / height;
358 if (row >= 0 && row < _label_stack.get_num_labels()) {
359 return _label_stack.get_label_collector_index(row);
368 void GtkStatsPianoRoll::
370 _label_stack.clear_labels();
371 for (
int i = 0; i < get_num_labels(); i++) {
372 _label_stack.add_label(GtkStatsGraph::_monitor,
this,
374 get_label_collector(i),
true);
376 _labels_changed =
false;
382 void GtkStatsPianoRoll::
384 int x = height_to_pixel(bar._height);
386 if (x > 0 && x < get_xsize() - 1) {
388 switch (bar._style) {
390 gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_light_gray);
394 gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_user_guide_bar);
398 gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_dark_gray);
401 gdk_draw_line(surface, _pixmap_gc, x, 0, x, get_ysize());
408 void GtkStatsPianoRoll::
409 draw_guide_labels() {
411 int num_guide_bars = get_num_guide_bars();
412 for (i = 0; i < num_guide_bars; i++) {
413 draw_guide_label(get_guide_bar(i));
416 int num_user_guide_bars = get_num_user_guide_bars();
417 for (i = 0; i < num_user_guide_bars; i++) {
418 draw_guide_label(get_user_guide_bar(i));
425 void GtkStatsPianoRoll::
427 GdkGC *gc = gdk_gc_new(_scale_area->window);
429 switch (bar._style) {
431 gdk_gc_set_rgb_fg_color(gc, &rgb_light_gray);
435 gdk_gc_set_rgb_fg_color(gc, &rgb_user_guide_bar);
439 gdk_gc_set_rgb_fg_color(gc, &rgb_dark_gray);
443 int x = height_to_pixel(bar._height);
444 const std::string &label = bar._label;
446 PangoLayout *layout = gtk_widget_create_pango_layout(_window, label.c_str());
448 pango_layout_get_pixel_size(layout, &width, &height);
450 if (bar._style != GBS_user) {
451 double from_height = pixel_to_height(x - width);
452 double to_height = pixel_to_height(x + width);
453 if (find_user_guide_bar(from_height, to_height) >= 0) {
455 g_object_unref(layout);
461 if (x >= 0 && x < get_xsize()) {
466 gtk_widget_translate_coordinates(_graph_window, _scale_area,
470 int this_x = x - width / 2;
471 gdk_draw_layout(_scale_area->window, gc, this_x,
472 _scale_area->allocation.height - height, layout);
475 g_object_unref(layout);
482 gboolean GtkStatsPianoRoll::
483 expose_event_callback(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
485 self->draw_guide_labels();
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 ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is an abstract class that presents the interface for drawing a piano- roll type chart: it shows ...
The data associated with a particular client, but not with any one particular frame or thread: the li...
A window that draws a piano-roll style chart, which shows the collectors explicitly stopping and star...
virtual void clicked_label(int collector_index)
Called when the user single-clicks on a label.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_horizontal_scale(double time_width)
Changes the amount of time the width of the horizontal axis represents.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void new_data(int thread_index, int frame_number)
Called as each frame's data is made available.
virtual void force_redraw()
Called when it is necessary to redraw the entire graph.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is just an abstract base class to provide a common pointer type for the various kinds of graphs ...
This class represents a connection to a PStatsClient and manages the data exchange with the client.
void open_strip_chart(int thread_index, int collector_index, bool show_level)
Opens a new strip chart showing the indicated data.
void set_horizontal_scale(double time_width)
Changes the amount of time the width of the horizontal axis represents.
const PStatClientData * get_client_data() const
Returns the client data associated with this monitor.
virtual void clicked_label(int collector_index)
Called when the user single-clicks on a label.
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.
std::string get_thread_name(int index) const
Returns the name of the indicated thread.