Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

pandatool/src/gtk-stats/gtkStatsStripChart.cxx

Go to the documentation of this file.
00001 // Filename: gtkStatsStripChart.cxx
00002 // Created by:  drose (14Jul00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "gtkStatsStripChart.h"
00020 #include "gtkStatsLabel.h"
00021 #include "gtkStatsGuide.h"
00022 
00023 #include <request_initial_size.h>
00024 #include <pStatThreadData.h>
00025 #include <pStatFrameData.h>
00026 #include <pStatView.h>
00027 
00028 #include <algorithm>
00029 
00030 
00031 ////////////////////////////////////////////////////////////////////
00032 //     Function: GtkStatsStripChart::Constructor
00033 //       Access: Public
00034 //  Description:
00035 ////////////////////////////////////////////////////////////////////
00036 GtkStatsStripChart::
00037 GtkStatsStripChart(GtkStatsMonitor *monitor, PStatView &view,
00038                    int collector_index, int xsize, int ysize) :
00039   PStatStripChart(monitor, view, collector_index, xsize, ysize)
00040 {
00041   _is_dead = false;
00042   set_events(GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
00043 
00044   _label_align = manage(new Gtk::Alignment(1.0, 1.0));
00045   _label_align->show();
00046 
00047   _label_box = NULL;
00048   pack_labels();
00049 
00050   _guide = manage(new GtkStatsGuide(this));
00051   _guide->show();
00052 
00053   request_initial_size(*this, get_xsize(), get_ysize());
00054 }
00055 
00056 ////////////////////////////////////////////////////////////////////
00057 //     Function: GtkStatsStripChart::mark_dead
00058 //       Access: Public
00059 //  Description: Called when the client's connection has been lost,
00060 //               this should update the window in some obvious way to
00061 //               indicate that the window is no longer live.
00062 ////////////////////////////////////////////////////////////////////
00063 void GtkStatsStripChart::
00064 mark_dead() {
00065   _is_dead = true;
00066 
00067   setup_white_gc();
00068 
00069   if (!first_data()) {
00070     force_redraw();
00071   } else {
00072     clear_region();
00073   }
00074 }
00075 
00076 ////////////////////////////////////////////////////////////////////
00077 //     Function: GtkStatsStripChart::get_labels
00078 //       Access: Public
00079 //  Description: Returns an alignment widget that contains all of the
00080 //               labels appropriate to this chart, already formatted
00081 //               and stacked up bottom-to-top.  The window should pack
00082 //               this widget suitably near the strip chart.
00083 ////////////////////////////////////////////////////////////////////
00084 Gtk::Alignment *GtkStatsStripChart::
00085 get_labels() {
00086   return _label_align;
00087 }
00088 
00089 ////////////////////////////////////////////////////////////////////
00090 //     Function: GtkStatsStripChart::get_guide
00091 //       Access: Public
00092 //  Description: Returns a widget that contains the numeric labels for
00093 //               the guide bars.  The window should pack this widget
00094 //               suitably near the strip chart.
00095 ////////////////////////////////////////////////////////////////////
00096 GtkStatsGuide *GtkStatsStripChart::
00097 get_guide() {
00098   return _guide;
00099 }
00100 
00101 
00102 ////////////////////////////////////////////////////////////////////
00103 //     Function: GtkStatsStripChart::get_collector_gc
00104 //       Access: Public
00105 //  Description: Returns a graphics context suitable for drawing in
00106 //               the indicated collector's color.
00107 ////////////////////////////////////////////////////////////////////
00108 Gdk_GC GtkStatsStripChart::
00109 get_collector_gc(int collector_index) {
00110   GCs::iterator gi;
00111   gi = _gcs.find(collector_index);
00112   if (gi != _gcs.end()) {
00113     return (*gi).second;
00114   }
00115 
00116   // Ask the monitor what color this guy should be.
00117   RGBColorf rgb = get_monitor()->get_collector_color(collector_index);
00118   Gdk_Color color;
00119   color.set_rgb_p(rgb[0], rgb[1], rgb[2]);
00120 
00121   // Now allocate the color from the system colormap.
00122   Gdk_Colormap::get_system().alloc(color);
00123 
00124   // Allocate a new graphics context.
00125   Gdk_GC gc(_pixmap);
00126   gc.set_foreground(color);
00127 
00128   _gcs[collector_index] = gc;
00129   return gc;
00130 }
00131 
00132 ////////////////////////////////////////////////////////////////////
00133 //     Function: GtkStatsStripChart::clear_region
00134 //       Access: Protected, Virtual
00135 //  Description: Erases the chart area.
00136 ////////////////////////////////////////////////////////////////////
00137 void GtkStatsStripChart::
00138 clear_region() {
00139   _pixmap.draw_rectangle(_white_gc, true, 0, 0, get_xsize(), get_ysize());
00140   end_draw(0, get_xsize());
00141 }
00142 
00143 ////////////////////////////////////////////////////////////////////
00144 //     Function: GtkStatsStripChart::copy_region
00145 //       Access: Protected, Virtual
00146 //  Description: Should be overridden by the user class to copy a
00147 //               region of the chart from one part of the chart to
00148 //               another.  This is used to implement scrolling.
00149 ////////////////////////////////////////////////////////////////////
00150 void GtkStatsStripChart::
00151 copy_region(int start_x, int end_x, int dest_x) {
00152   _pixmap.copy_area(_white_gc, 0, 0,
00153                     _pixmap, start_x, 0,
00154                     end_x - start_x + 1, get_ysize());
00155 
00156   // We could make a window-to-window copy to implement scrolling in
00157   // the window.  But this leads to trouble if the scrolling window
00158   // isn't on top.  Instead, we'll just do the scroll in the pixmap,
00159   // and then blt the pixmap back out--in principle, this ought to be
00160   // just as fast.
00161   /*
00162   Gdk_Window window = get_window();
00163   window.copy_area(_white_gc, 0, 0,
00164                    window, start_x, 0,
00165                    end_x - start_x + 1, get_ysize());
00166   */
00167 
00168   GdkRectangle update_rect;
00169   update_rect.x = dest_x;
00170   update_rect.y = 0;
00171   update_rect.width = end_x - start_x + 1;
00172   update_rect.height = get_ysize();
00173   draw(&update_rect);
00174 }
00175 
00176 ////////////////////////////////////////////////////////////////////
00177 //     Function: GtkStatsStripChart::draw_slice
00178 //       Access: Protected, Virtual
00179 //  Description: Draws a single vertical slice of the strip chart, at
00180 //               the given pixel position, and corresponding to the
00181 //               indicated level data.
00182 ////////////////////////////////////////////////////////////////////
00183 void GtkStatsStripChart::
00184 draw_slice(int x, int frame_number) {
00185   const FrameData &frame = get_frame_data(frame_number);
00186 
00187   // Start by clearing the band first.
00188   _pixmap.draw_line(_white_gc, x, 0, x, get_ysize());
00189 
00190   float overall_time = 0.0;
00191   int y = get_ysize();
00192 
00193   FrameData::const_iterator fi;
00194   for (fi = frame.begin(); fi != frame.end(); ++fi) {
00195     const ColorData &cd = (*fi);
00196     overall_time += cd._net_value;
00197 
00198     if (overall_time > get_vertical_scale()) {
00199       // Off the top.  Go ahead and clamp it by hand, in case it's so
00200       // far off the top we'd overflow the 16-bit pixel value.
00201       _pixmap.draw_line(get_collector_gc(cd._collector_index), x, y, x, 0);
00202       // And we can consider ourselves done now.
00203       return;
00204     }
00205 
00206     int top_y = height_to_pixel(overall_time);
00207     _pixmap.draw_line(get_collector_gc(cd._collector_index), x, y, x, top_y);
00208     y = top_y;
00209   }
00210 }
00211 
00212 ////////////////////////////////////////////////////////////////////
00213 //     Function: GtkStatsStripChart::draw_empty
00214 //       Access: Protected, Virtual
00215 //  Description: Draws a single vertical slice of background color.
00216 ////////////////////////////////////////////////////////////////////
00217 void GtkStatsStripChart::
00218 draw_empty(int x) {
00219   _pixmap.draw_line(_white_gc, x, 0, x, get_ysize());
00220 }
00221 
00222 ////////////////////////////////////////////////////////////////////
00223 //     Function: GtkStatsStripChart::draw_cursor
00224 //       Access: Protected, Virtual
00225 //  Description: Draws a single vertical slice of foreground color.
00226 ////////////////////////////////////////////////////////////////////
00227 void GtkStatsStripChart::
00228 draw_cursor(int x) {
00229   _pixmap.draw_line(_black_gc, x, 0, x, get_ysize());
00230 }
00231 
00232 ////////////////////////////////////////////////////////////////////
00233 //     Function: GtkStatsStripChart::end_draw
00234 //       Access: Protected, Virtual
00235 //  Description: Should be overridden by the user class.  This hook
00236 //               will be called after drawing a series of color bars
00237 //               in the strip chart; it gives the pixel range that
00238 //               was just redrawn.
00239 ////////////////////////////////////////////////////////////////////
00240 void GtkStatsStripChart::
00241 end_draw(int from_x, int to_x) {
00242   // Draw in the guide bars.
00243   int num_guide_bars = get_num_guide_bars();
00244   for (int i = 0; i < num_guide_bars; i++) {
00245     const GuideBar &bar = get_guide_bar(i);
00246     int y = height_to_pixel(bar._height);
00247 
00248     if (y >= 5) {
00249       // Only draw it if it's not too close to the top.
00250       if (bar._is_target) {
00251         _pixmap.draw_line(_light_gc, from_x, y, to_x, y);
00252       } else {
00253         _pixmap.draw_line(_dark_gc, from_x, y, to_x, y);
00254       }
00255     }
00256   }
00257 
00258   GdkRectangle update_rect;
00259   update_rect.x = from_x;
00260   update_rect.y = 0;
00261   update_rect.width = to_x - from_x + 1;
00262   update_rect.height = get_ysize();
00263   draw(&update_rect);
00264 }
00265 
00266 ////////////////////////////////////////////////////////////////////
00267 //     Function: GtkStatsStripChart::idle
00268 //       Access: Protected, Virtual
00269 //  Description: Called at the end of the draw cycle.
00270 ////////////////////////////////////////////////////////////////////
00271 void GtkStatsStripChart::
00272 idle() {
00273   if (_labels_changed) {
00274     pack_labels();
00275   }
00276   if (_guide_bars_changed) {
00277     GdkRectangle update_rect;
00278     update_rect.x = 0;
00279     update_rect.y = 0;
00280     update_rect.width = _guide->width();
00281     update_rect.height = _guide->height();
00282     _guide->draw(&update_rect);
00283     _guide_bars_changed = false;
00284   }
00285 }
00286 
00287 ////////////////////////////////////////////////////////////////////
00288 //     Function: GtkStatsStripChart::configure_event_impl
00289 //       Access: Private, Virtual
00290 //  Description: Creates a new backing pixmap of the appropriate size.
00291 ////////////////////////////////////////////////////////////////////
00292 gint GtkStatsStripChart::
00293 configure_event_impl(GdkEventConfigure *) {
00294   if (width() != get_xsize() || height() != get_ysize() ||
00295       _pixmap.gdkobj() == (GdkDrawable *)NULL) {
00296     bool is_initial = true;
00297     if (_pixmap) {
00298       is_initial = false;
00299       _pixmap.release();
00300     }
00301 
00302     _pixmap.create(get_window(), width(), height());
00303 
00304     Gdk_Colormap system_colormap = Gdk_Colormap::get_system();
00305 
00306     _white_gc = Gdk_GC(_pixmap);
00307     setup_white_gc();
00308 
00309     _black_gc = Gdk_GC(_pixmap);
00310     _black_gc.set_foreground(system_colormap.black());
00311 
00312     _dark_gc = Gdk_GC(_pixmap);
00313     Gdk_Color dark;
00314     dark.set_grey_p(0.2);
00315     system_colormap.alloc(dark);
00316     _dark_gc.set_foreground(dark);
00317 
00318     _light_gc = Gdk_GC(_pixmap);
00319     Gdk_Color light;
00320     light.set_grey_p(0.6);
00321     system_colormap.alloc(light);
00322     _light_gc.set_foreground(light);
00323 
00324     _pixmap.draw_rectangle(_white_gc, true, 0, 0, width(), height());
00325 
00326     changed_size(width(), height());
00327   }
00328   return true;
00329 }
00330 
00331 ////////////////////////////////////////////////////////////////////
00332 //     Function: GtkStatsStripChart::expose_event_impl
00333 //       Access: Private, Virtual
00334 //  Description: Redraw the screen from the backing pixmap.
00335 ////////////////////////////////////////////////////////////////////
00336 gint GtkStatsStripChart::
00337 expose_event_impl(GdkEventExpose *event) {
00338   get_window().draw_pixmap(_white_gc, _pixmap,
00339                            event->area.x, event->area.y,
00340                            event->area.x, event->area.y,
00341                            event->area.width, event->area.height);
00342 
00343   return false;
00344 }
00345 
00346 ////////////////////////////////////////////////////////////////////
00347 //     Function: GtkStatsStripChart::button_press_event_impl
00348 //       Access: Private, Virtual
00349 //  Description:
00350 ////////////////////////////////////////////////////////////////////
00351 gint GtkStatsStripChart::
00352 button_press_event_impl(GdkEventButton *button) {
00353   if (button->type == GDK_2BUTTON_PRESS && button->button == 1) {
00354     int collector_index = get_collector_under_pixel(button->x, button->y);
00355     collector_picked(collector_index);
00356     return true;
00357   }
00358   return false;
00359 }
00360 
00361 
00362 ////////////////////////////////////////////////////////////////////
00363 //     Function: GtkStatsStripChart::pack_labels
00364 //       Access: Private
00365 //  Description:
00366 ////////////////////////////////////////////////////////////////////
00367 void GtkStatsStripChart::
00368 pack_labels() {
00369   // First, remove the old labels.
00370   _label_align->remove();
00371 
00372   // Now add the new labels back in.
00373   _label_box = manage(new Gtk::VBox);
00374   _label_box->show();
00375   _label_align->add(*_label_box);
00376 
00377   Gdk_Font font = get_style()->gtkobj()->font;
00378 
00379   int num_labels = get_num_labels();
00380   for (int i = 0; i < num_labels; i++) {
00381     int collector_index = get_label_collector(i);
00382     GtkStatsLabel *label =
00383       new GtkStatsLabel(get_monitor(), collector_index, font);
00384     label->show();
00385     
00386     label->collector_picked.connect(collector_picked.slot());
00387     
00388     _label_box->pack_end(*manage(label), false, false);
00389   }
00390   
00391   _labels_changed = false;
00392 }
00393 
00394 ////////////////////////////////////////////////////////////////////
00395 //     Function: GtkStatsStripChart::setup_white_gc
00396 //       Access: Private
00397 //  Description: Sets the color on _white_gc to be either actually
00398 //               white (if the chart is still alive) or a light gray
00399 //               (if the chart is dead).
00400 ////////////////////////////////////////////////////////////////////
00401 void GtkStatsStripChart::
00402 setup_white_gc() {
00403   Gdk_Colormap system_colormap = Gdk_Colormap::get_system();
00404 
00405   if (_is_dead) {
00406     Gdk_Color death;
00407     death.set_grey_p(0.8);
00408     system_colormap.alloc(death);
00409 
00410     _white_gc.set_foreground(death);
00411 
00412   } else {
00413     _white_gc.set_foreground(system_colormap.white());
00414   }
00415 
00416 }
00417 

Generated on Fri May 2 03:20:03 2003 for Panda-Tool by doxygen1.3