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

pandatool/src/gtk-stats/gtkStatsPianoRoll.cxx

Go to the documentation of this file.
00001 // Filename: gtkStatsPianoRoll.cxx
00002 // Created by:  drose (18Jul00)
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 "gtkStatsPianoRoll.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: GtkStatsPianoRoll::Constructor
00033 //       Access: Public
00034 //  Description:
00035 ////////////////////////////////////////////////////////////////////
00036 GtkStatsPianoRoll::
00037 GtkStatsPianoRoll(GtkStatsMonitor *monitor, int thread_index,
00038                   int xsize, int ysize) :
00039   PStatPianoRoll(monitor, thread_index, xsize, ysize)
00040 {
00041   _is_dead = false;
00042   set_events(GDK_EXPOSURE_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   request_initial_size(*this, get_xsize(), get_ysize());
00051 }
00052 
00053 ////////////////////////////////////////////////////////////////////
00054 //     Function: GtkStatsPianoRoll::mark_dead
00055 //       Access: Public
00056 //  Description: Called when the client's connection has been lost,
00057 //               this should update the window in some obvious way to
00058 //               indicate that the window is no longer live.
00059 ////////////////////////////////////////////////////////////////////
00060 void GtkStatsPianoRoll::
00061 mark_dead() {
00062   _is_dead = true;
00063 
00064   setup_white_gc();
00065   force_redraw();
00066 }
00067 
00068 
00069 ////////////////////////////////////////////////////////////////////
00070 //     Function: GtkStatsPianoRoll::get_labels
00071 //       Access: Public
00072 //  Description: Returns an alignment widget that contains all of the
00073 //               labels appropriate to this chart, already formatted
00074 //               and stacked up bottom-to-top.  The window should pack
00075 //               this widget suitably near the strip chart.
00076 ////////////////////////////////////////////////////////////////////
00077 Gtk::Alignment *GtkStatsPianoRoll::
00078 get_labels() {
00079   return _label_align;
00080 }
00081 
00082 ////////////////////////////////////////////////////////////////////
00083 //     Function: GtkStatsPianoRoll::get_collector_gc
00084 //       Access: Public
00085 //  Description: Returns a graphics context suitable for drawing in
00086 //               the indicated collector's color.
00087 ////////////////////////////////////////////////////////////////////
00088 Gdk_GC GtkStatsPianoRoll::
00089 get_collector_gc(int collector_index) {
00090   GCs::iterator gi;
00091   gi = _gcs.find(collector_index);
00092   if (gi != _gcs.end()) {
00093     return (*gi).second;
00094   }
00095 
00096   // Ask the monitor what color this guy should be.
00097   RGBColorf rgb = get_monitor()->get_collector_color(collector_index);
00098   Gdk_Color color;
00099   color.set_rgb_p(rgb[0], rgb[1], rgb[2]);
00100 
00101   // Now allocate the color from the system colormap.
00102   Gdk_Colormap::get_system().alloc(color);
00103 
00104   // Allocate a new graphics context.
00105   Gdk_GC gc(_pixmap);
00106   gc.set_foreground(color);
00107 
00108   _gcs[collector_index] = gc;
00109   return gc;
00110 }
00111 
00112 ////////////////////////////////////////////////////////////////////
00113 //     Function: GtkStatsPianoRoll::begin_draw
00114 //       Access: Protected, Virtual
00115 //  Description: Erases the chart area in preparation for drawing it
00116 //               full of bars.
00117 ////////////////////////////////////////////////////////////////////
00118 void GtkStatsPianoRoll::
00119 begin_draw() {
00120   _pixmap.draw_rectangle(_white_gc, true, 0, 0, get_xsize(), get_ysize());
00121 
00122   Gdk_Font font = get_style()->gtkobj()->font;
00123   int text_height = font.height();
00124 
00125   // Draw in the guide bars.
00126   int num_guide_bars = get_num_guide_bars();
00127   for (int i = 0; i < num_guide_bars; i++) {
00128     const GuideBar &bar = get_guide_bar(i);
00129     int x = (int)((float)get_xsize() * bar._height / get_horizontal_scale());
00130 
00131     if (x >= 5 && x <= get_xsize() - 5) {
00132       // Only draw it if it's not too close to either edge.
00133       if (bar._is_target) {
00134         _pixmap.draw_line(_light_gc, x, text_height + 4, x, get_ysize());
00135       } else {
00136         _pixmap.draw_line(_dark_gc, x, text_height + 4, x, get_ysize());
00137       }
00138     }
00139   }
00140 
00141 }
00142 
00143 ////////////////////////////////////////////////////////////////////
00144 //     Function: GtkStatsPianoRoll::draw_bar
00145 //       Access: Protected, Virtual
00146 //  Description: Draws a single bar on the chart.
00147 ////////////////////////////////////////////////////////////////////
00148 void GtkStatsPianoRoll::
00149 draw_bar(int row, int from_x, int to_x) {
00150   if (row >= 0 && row < (int)_y_positions.size()) {
00151     int y = height() - _y_positions[row];
00152     _pixmap.draw_rectangle(get_collector_gc(get_label_collector(row)),
00153                            true, from_x, y - 6, to_x - from_x, 12);
00154   }
00155 }
00156 
00157 ////////////////////////////////////////////////////////////////////
00158 //     Function: GtkStatsPianoRoll::end_draw
00159 //       Access: Protected, Virtual
00160 //  Description: Called after all the bars have been drawn, this
00161 //               triggers a refresh event to draw it to the window.
00162 ////////////////////////////////////////////////////////////////////
00163 void GtkStatsPianoRoll::
00164 end_draw() {
00165   // Draw in the labels for the guide bars.  We do this in end_draw()
00166   // instead of in begin_draw() so the labels will appear on top of
00167   // any of the color bars.
00168   Gdk_Font font = get_style()->gtkobj()->font;
00169   int text_ascent = font.ascent();
00170 
00171   int num_guide_bars = get_num_guide_bars();
00172   for (int i = 0; i < num_guide_bars; i++) {
00173     const GuideBar &bar = get_guide_bar(i);
00174     int x = (int)((float)get_xsize() * bar._height / get_horizontal_scale());
00175 
00176     if (x >= 5 && x <= get_xsize() - 5) {
00177       // Only draw it if it's not too close to either edge.
00178       int width = font.string_measure(bar._label);
00179       _pixmap.draw_string(font, _black_gc, x - width / 2, text_ascent + 2,
00180                           bar._label);
00181     }
00182   }
00183 
00184   GdkRectangle update_rect;
00185   update_rect.x = 0;
00186   update_rect.y = 0;
00187   update_rect.width = get_xsize();
00188   update_rect.height = get_ysize();
00189   draw(&update_rect);
00190 }
00191 
00192 ////////////////////////////////////////////////////////////////////
00193 //     Function: GtkStatsPianoRoll::idle
00194 //       Access: Protected, Virtual
00195 //  Description: Called at the end of the draw cycle.
00196 ////////////////////////////////////////////////////////////////////
00197 void GtkStatsPianoRoll::
00198 idle() {
00199   if (_labels_changed) {
00200     pack_labels();
00201   }
00202 }
00203 
00204 ////////////////////////////////////////////////////////////////////
00205 //     Function: GtkStatsPianoRoll::configure_event_impl
00206 //       Access: Private, Virtual
00207 //  Description: Creates a new backing pixmap of the appropriate size.
00208 ////////////////////////////////////////////////////////////////////
00209 gint GtkStatsPianoRoll::
00210 configure_event_impl(GdkEventConfigure *) {
00211   if (width() != get_xsize() || height() != get_ysize() ||
00212       _pixmap.gdkobj() == (GdkDrawable *)NULL) {
00213     if (_pixmap) {
00214       _pixmap.release();
00215     }
00216 
00217     _pixmap.create(get_window(), width(), height());
00218 
00219     Gdk_Colormap system_colormap = Gdk_Colormap::get_system();
00220 
00221     _white_gc = Gdk_GC(_pixmap);
00222     setup_white_gc();
00223 
00224     _black_gc = Gdk_GC(_pixmap);
00225     _black_gc.set_foreground(system_colormap.black());
00226 
00227     _dark_gc = Gdk_GC(_pixmap);
00228     Gdk_Color dark;
00229     dark.set_grey_p(0.2);
00230     system_colormap.alloc(dark);
00231     _dark_gc.set_foreground(dark);
00232 
00233     _light_gc = Gdk_GC(_pixmap);
00234     Gdk_Color light;
00235     light.set_grey_p(0.6);
00236     system_colormap.alloc(light);
00237     _light_gc.set_foreground(light);
00238 
00239     _pixmap.draw_rectangle(_white_gc, true, 0, 0, width(), height());
00240 
00241     changed_size(width(), height());
00242   }
00243   return true;
00244 }
00245 
00246 ////////////////////////////////////////////////////////////////////
00247 //     Function: GtkStatsPianoRoll::expose_event_impl
00248 //       Access: Private, Virtual
00249 //  Description: Redraw the screen from the backing pixmap.
00250 ////////////////////////////////////////////////////////////////////
00251 gint GtkStatsPianoRoll::
00252 expose_event_impl(GdkEventExpose *event) {
00253   get_window().draw_pixmap(_white_gc, _pixmap,
00254                            event->area.x, event->area.y,
00255                            event->area.x, event->area.y,
00256                            event->area.width, event->area.height);
00257 
00258   return false;
00259 }
00260 
00261 ////////////////////////////////////////////////////////////////////
00262 //     Function: GtkStatsPianoRoll::pack_labels
00263 //       Access: Private
00264 //  Description:
00265 ////////////////////////////////////////////////////////////////////
00266 void GtkStatsPianoRoll::
00267 pack_labels() {
00268   // First, remove the old labels.
00269   _label_align->remove();
00270 
00271   // Now add the new labels back in.
00272   _label_box = manage(new Gtk::VBox);
00273   _label_box->show();
00274   _label_align->add(*_label_box);
00275 
00276   Gdk_Font font = get_style()->gtkobj()->font;
00277   int num_labels = get_num_labels();
00278 
00279   while ((int)_y_positions.size() < num_labels) {
00280     _y_positions.push_back(0);
00281   }
00282 
00283   int y = 0;
00284   for (int i = 0; i < num_labels; i++) {
00285     int collector_index = get_label_collector(i);
00286     GtkStatsLabel *label =
00287       new GtkStatsLabel(get_monitor(), collector_index, font);
00288     label->show();
00289 
00290     _label_box->pack_end(*manage(label), false, false);
00291     _y_positions[i] = y + label->get_height() / 2;
00292 
00293     y += label->get_height();
00294   }
00295 
00296   _labels_changed = false;
00297 }
00298 
00299 ////////////////////////////////////////////////////////////////////
00300 //     Function: GtkStatsPianoRoll::setup_white_gc
00301 //       Access: Private
00302 //  Description: Sets the color on _white_gc to be either actually
00303 //               white (if the chart is still alive) or a light gray
00304 //               (if the chart is dead).
00305 ////////////////////////////////////////////////////////////////////
00306 void GtkStatsPianoRoll::
00307 setup_white_gc() {
00308   Gdk_Colormap system_colormap = Gdk_Colormap::get_system();
00309 
00310   if (_is_dead) {
00311     Gdk_Color death;
00312     death.set_grey_p(0.8);
00313     system_colormap.alloc(death);
00314 
00315     _white_gc.set_foreground(death);
00316 
00317   } else {
00318     _white_gc.set_foreground(system_colormap.white());
00319   }
00320 
00321 }
00322 

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