| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425 |
- // Filename: gtkStatsStripChart.cxx
- // Created by: drose (14Jul00)
- //
- ////////////////////////////////////////////////////////////////////
- //
- // PANDA 3D SOFTWARE
- // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
- //
- // All use of this software is subject to the terms of the Panda 3d
- // Software license. You should have received a copy of this license
- // along with this source code; you will also find a current copy of
- // the license at http://www.panda3d.org/license.txt .
- //
- // To contact the maintainers of this program write to
- // [email protected] .
- //
- ////////////////////////////////////////////////////////////////////
- #include "gtkStatsStripChart.h"
- #include "gtkStatsLabel.h"
- #include "gtkStatsGuide.h"
- #include <request_initial_size.h>
- #include <pStatThreadData.h>
- #include <pStatFrameData.h>
- #include <pStatView.h>
- #include <algorithm>
- ////////////////////////////////////////////////////////////////////
- // Function: GtkStatsStripChart::Constructor
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- GtkStatsStripChart::
- GtkStatsStripChart(GtkStatsMonitor *monitor, PStatView &view,
- int collector_index, int xsize, int ysize) :
- PStatStripChart(monitor, view, collector_index, xsize, ysize)
- {
- _is_dead = false;
- set_events(GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
- _label_align = manage(new Gtk::Alignment(1.0, 1.0));
- _label_align->show();
- _label_box = NULL;
- pack_labels();
- _guide = manage(new GtkStatsGuide(this));
- _guide->show();
- request_initial_size(*this, get_xsize(), get_ysize());
- }
- ////////////////////////////////////////////////////////////////////
- // Function: GtkStatsStripChart::mark_dead
- // Access: Public
- // Description: Called when the client's connection has been lost,
- // this should update the window in some obvious way to
- // indicate that the window is no longer live.
- ////////////////////////////////////////////////////////////////////
- void GtkStatsStripChart::
- mark_dead() {
- _is_dead = true;
- setup_white_gc();
- if (!first_data()) {
- force_redraw();
- } else {
- clear_region();
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: GtkStatsStripChart::get_labels
- // Access: Public
- // Description: Returns an alignment widget that contains all of the
- // labels appropriate to this chart, already formatted
- // and stacked up bottom-to-top. The window should pack
- // this widget suitably near the strip chart.
- ////////////////////////////////////////////////////////////////////
- Gtk::Alignment *GtkStatsStripChart::
- get_labels() {
- return _label_align;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: GtkStatsStripChart::get_guide
- // Access: Public
- // Description: Returns a widget that contains the numeric labels for
- // the guide bars. The window should pack this widget
- // suitably near the strip chart.
- ////////////////////////////////////////////////////////////////////
- GtkStatsGuide *GtkStatsStripChart::
- get_guide() {
- return _guide;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: GtkStatsStripChart::get_collector_gc
- // Access: Public
- // Description: Returns a graphics context suitable for drawing in
- // the indicated collector's color.
- ////////////////////////////////////////////////////////////////////
- Gdk_GC GtkStatsStripChart::
- get_collector_gc(int collector_index) {
- GCs::iterator gi;
- gi = _gcs.find(collector_index);
- if (gi != _gcs.end()) {
- return (*gi).second;
- }
- // Ask the monitor what color this guy should be.
- RGBColorf rgb = get_monitor()->get_collector_color(collector_index);
- Gdk_Color color;
- color.set_rgb_p(rgb[0], rgb[1], rgb[2]);
- // Now allocate the color from the system colormap.
- Gdk_Colormap::get_system().alloc(color);
- // Allocate a new graphics context.
- Gdk_GC gc(_pixmap);
- gc.set_foreground(color);
- _gcs[collector_index] = gc;
- return gc;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: GtkStatsStripChart::clear_region
- // Access: Protected, Virtual
- // Description: Erases the chart area.
- ////////////////////////////////////////////////////////////////////
- void GtkStatsStripChart::
- clear_region() {
- _pixmap.draw_rectangle(_white_gc, true, 0, 0, get_xsize(), get_ysize());
- end_draw(0, get_xsize());
- }
- ////////////////////////////////////////////////////////////////////
- // Function: GtkStatsStripChart::copy_region
- // Access: Protected, Virtual
- // Description: Should be overridden by the user class to copy a
- // region of the chart from one part of the chart to
- // another. This is used to implement scrolling.
- ////////////////////////////////////////////////////////////////////
- void GtkStatsStripChart::
- copy_region(int start_x, int end_x, int dest_x) {
- _pixmap.copy_area(_white_gc, 0, 0,
- _pixmap, start_x, 0,
- end_x - start_x + 1, get_ysize());
- // We could make a window-to-window copy to implement scrolling in
- // the window. But this leads to trouble if the scrolling window
- // isn't on top. Instead, we'll just do the scroll in the pixmap,
- // and then blt the pixmap back out--in principle, this ought to be
- // just as fast.
- /*
- Gdk_Window window = get_window();
- window.copy_area(_white_gc, 0, 0,
- window, start_x, 0,
- end_x - start_x + 1, get_ysize());
- */
- GdkRectangle update_rect;
- update_rect.x = dest_x;
- update_rect.y = 0;
- update_rect.width = end_x - start_x + 1;
- update_rect.height = get_ysize();
- draw(&update_rect);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: GtkStatsStripChart::draw_slice
- // Access: Protected, Virtual
- // Description: Draws a single vertical slice of the strip chart, at
- // the given pixel position, and corresponding to the
- // indicated level data.
- ////////////////////////////////////////////////////////////////////
- void GtkStatsStripChart::
- draw_slice(int x, int w, int frame_number) {
- const FrameData &frame = get_frame_data(frame_number);
- while (w > 0) {
- // Start by clearing the band first.
- _pixmap.draw_line(_white_gc, x, 0, x, get_ysize());
- float overall_time = 0.0;
- int y = get_ysize();
- FrameData::const_iterator fi;
- for (fi = frame.begin(); fi != frame.end(); ++fi) {
- const ColorData &cd = (*fi);
- overall_time += cd._net_value;
- if (overall_time > get_vertical_scale()) {
- // Off the top. Go ahead and clamp it by hand, in case it's so
- // far off the top we'd overflow the 16-bit pixel value.
- _pixmap.draw_line(get_collector_gc(cd._collector_index), x, y, x, 0);
- // And we can consider ourselves done now.
- break;
- }
- int top_y = height_to_pixel(overall_time);
- _pixmap.draw_line(get_collector_gc(cd._collector_index), x, y, x, top_y);
- y = top_y;
- }
- x++;
- w--;
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: GtkStatsStripChart::draw_empty
- // Access: Protected, Virtual
- // Description: Draws a single vertical slice of background color.
- ////////////////////////////////////////////////////////////////////
- void GtkStatsStripChart::
- draw_empty(int x, int w) {
- while (w > 0) {
- _pixmap.draw_line(_white_gc, x, 0, x, get_ysize());
- x++;
- w--;
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: GtkStatsStripChart::draw_cursor
- // Access: Protected, Virtual
- // Description: Draws a single vertical slice of foreground color.
- ////////////////////////////////////////////////////////////////////
- void GtkStatsStripChart::
- draw_cursor(int x) {
- _pixmap.draw_line(_black_gc, x, 0, x, get_ysize());
- }
- ////////////////////////////////////////////////////////////////////
- // Function: GtkStatsStripChart::end_draw
- // Access: Protected, Virtual
- // Description: Should be overridden by the user class. This hook
- // will be called after drawing a series of color bars
- // in the strip chart; it gives the pixel range that
- // was just redrawn.
- ////////////////////////////////////////////////////////////////////
- void GtkStatsStripChart::
- end_draw(int from_x, int to_x) {
- // Draw in the guide bars.
- int num_guide_bars = get_num_guide_bars();
- for (int i = 0; i < num_guide_bars; i++) {
- const GuideBar &bar = get_guide_bar(i);
- int y = height_to_pixel(bar._height);
- if (y >= 5) {
- // Only draw it if it's not too close to the top.
- if (bar._is_target) {
- _pixmap.draw_line(_light_gc, from_x, y, to_x, y);
- } else {
- _pixmap.draw_line(_dark_gc, from_x, y, to_x, y);
- }
- }
- }
- GdkRectangle update_rect;
- update_rect.x = from_x;
- update_rect.y = 0;
- update_rect.width = to_x - from_x + 1;
- update_rect.height = get_ysize();
- draw(&update_rect);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: GtkStatsStripChart::idle
- // Access: Protected, Virtual
- // Description: Called at the end of the draw cycle.
- ////////////////////////////////////////////////////////////////////
- void GtkStatsStripChart::
- idle() {
- if (_labels_changed) {
- pack_labels();
- }
- if (_guide_bars_changed) {
- GdkRectangle update_rect;
- update_rect.x = 0;
- update_rect.y = 0;
- update_rect.width = _guide->width();
- update_rect.height = _guide->height();
- _guide->draw(&update_rect);
- _guide_bars_changed = false;
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: GtkStatsStripChart::configure_event_impl
- // Access: Private, Virtual
- // Description: Creates a new backing pixmap of the appropriate size.
- ////////////////////////////////////////////////////////////////////
- gint GtkStatsStripChart::
- configure_event_impl(GdkEventConfigure *) {
- if (width() != get_xsize() || height() != get_ysize() ||
- _pixmap.gdkobj() == (GdkDrawable *)NULL) {
- bool is_initial = true;
- if (_pixmap) {
- is_initial = false;
- _pixmap.release();
- }
- _pixmap.create(get_window(), width(), height());
- Gdk_Colormap system_colormap = Gdk_Colormap::get_system();
- _white_gc = Gdk_GC(_pixmap);
- setup_white_gc();
- _black_gc = Gdk_GC(_pixmap);
- _black_gc.set_foreground(system_colormap.black());
- _dark_gc = Gdk_GC(_pixmap);
- Gdk_Color dark;
- dark.set_grey_p(0.2);
- system_colormap.alloc(dark);
- _dark_gc.set_foreground(dark);
- _light_gc = Gdk_GC(_pixmap);
- Gdk_Color light;
- light.set_grey_p(0.6);
- system_colormap.alloc(light);
- _light_gc.set_foreground(light);
- _pixmap.draw_rectangle(_white_gc, true, 0, 0, width(), height());
- changed_size(width(), height());
- }
- return true;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: GtkStatsStripChart::expose_event_impl
- // Access: Private, Virtual
- // Description: Redraw the screen from the backing pixmap.
- ////////////////////////////////////////////////////////////////////
- gint GtkStatsStripChart::
- expose_event_impl(GdkEventExpose *event) {
- get_window().draw_pixmap(_white_gc, _pixmap,
- event->area.x, event->area.y,
- event->area.x, event->area.y,
- event->area.width, event->area.height);
- return false;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: GtkStatsStripChart::button_press_event_impl
- // Access: Private, Virtual
- // Description:
- ////////////////////////////////////////////////////////////////////
- gint GtkStatsStripChart::
- button_press_event_impl(GdkEventButton *button) {
- if (button->type == GDK_2BUTTON_PRESS && button->button == 1) {
- int collector_index = get_collector_under_pixel(button->x, button->y);
- collector_picked(collector_index);
- return true;
- }
- return false;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: GtkStatsStripChart::pack_labels
- // Access: Private
- // Description:
- ////////////////////////////////////////////////////////////////////
- void GtkStatsStripChart::
- pack_labels() {
- // First, remove the old labels.
- _label_align->remove();
- // Now add the new labels back in.
- _label_box = manage(new Gtk::VBox);
- _label_box->show();
- _label_align->add(*_label_box);
- Gdk_Font font = get_style()->gtkobj()->font;
- int num_labels = get_num_labels();
- for (int i = 0; i < num_labels; i++) {
- int collector_index = get_label_collector(i);
- GtkStatsLabel *label =
- new GtkStatsLabel(get_monitor(), collector_index, font);
- label->show();
-
- label->collector_picked.connect(collector_picked.slot());
-
- _label_box->pack_end(*manage(label), false, false);
- }
-
- _labels_changed = false;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: GtkStatsStripChart::setup_white_gc
- // Access: Private
- // Description: Sets the color on _white_gc to be either actually
- // white (if the chart is still alive) or a light gray
- // (if the chart is dead).
- ////////////////////////////////////////////////////////////////////
- void GtkStatsStripChart::
- setup_white_gc() {
- Gdk_Colormap system_colormap = Gdk_Colormap::get_system();
- if (_is_dead) {
- Gdk_Color death;
- death.set_grey_p(0.8);
- system_colormap.alloc(death);
- _white_gc.set_foreground(death);
- } else {
- _white_gc.set_foreground(system_colormap.white());
- }
- }
|