Panda3D
 All Classes Functions Variables Enumerations
gtkStatsLabel.cxx
00001 // Filename: gtkStatsLabel.cxx
00002 // Created by:  drose (16Jan06)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "gtkStatsLabel.h"
00016 #include "gtkStatsMonitor.h"
00017 #include "gtkStatsGraph.h"
00018 
00019 int GtkStatsLabel::_left_margin = 2;
00020 int GtkStatsLabel::_right_margin = 2;
00021 int GtkStatsLabel::_top_margin = 2;
00022 int GtkStatsLabel::_bottom_margin = 2;
00023 
00024 ////////////////////////////////////////////////////////////////////
00025 //     Function: GtkStatsLabel::Constructor
00026 //       Access: Public
00027 //  Description:
00028 ////////////////////////////////////////////////////////////////////
00029 GtkStatsLabel::
00030 GtkStatsLabel(GtkStatsMonitor *monitor, GtkStatsGraph *graph,
00031               int thread_index, int collector_index, bool use_fullname) :
00032   _monitor(monitor),
00033   _graph(graph),
00034   _thread_index(thread_index),
00035   _collector_index(collector_index)
00036 {
00037   _widget = NULL;
00038   if (use_fullname) {
00039     _text = _monitor->get_client_data()->get_collector_fullname(_collector_index);
00040   } else {
00041     _text = _monitor->get_client_data()->get_collector_name(_collector_index);
00042   }
00043 
00044   _widget = gtk_drawing_area_new();
00045   gtk_widget_add_events(_widget, 
00046       GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | 
00047       GDK_BUTTON_PRESS_MASK);
00048   g_signal_connect(G_OBJECT(_widget), "expose_event",  
00049        G_CALLBACK(expose_event_callback), this);
00050   g_signal_connect(G_OBJECT(_widget), "enter_notify_event",  
00051        G_CALLBACK(enter_notify_event_callback), this);
00052   g_signal_connect(G_OBJECT(_widget), "leave_notify_event",  
00053        G_CALLBACK(leave_notify_event_callback), this);
00054   g_signal_connect(G_OBJECT(_widget), "button_press_event",  
00055        G_CALLBACK(button_press_event_callback), this);
00056 
00057   gtk_widget_show(_widget);
00058 
00059   // Make up a PangoLayout to represent the text.
00060   _layout = gtk_widget_create_pango_layout(_widget, _text.c_str());
00061 
00062   // Set the fg and bg colors on the label.
00063   LRGBColor rgb = _monitor->get_collector_color(_collector_index);
00064   _bg_color.red = (int)(rgb[0] * 65535.0f);
00065   _bg_color.green = (int)(rgb[1] * 65535.0f);
00066   _bg_color.blue = (int)(rgb[2] * 65535.0f);
00067 
00068   // Should our foreground be black or white?
00069   double bright =
00070     rgb[0] * 0.299 +
00071     rgb[1] * 0.587 +
00072     rgb[2] * 0.114;
00073 
00074   if (bright >= 0.5) {
00075     _fg_color.red = _fg_color.green = _fg_color.blue = 0;
00076   } else {
00077     _fg_color.red = _fg_color.green = _fg_color.blue = 0xffff;
00078   }
00079 
00080   // What are the extents of the text?  This determines the minimum
00081   // size of our widget.
00082   int width, height;
00083   pango_layout_get_pixel_size(_layout, &width, &height);
00084   gtk_widget_set_size_request(_widget, width + 8, height);
00085 
00086   _highlight = false;
00087   _mouse_within = false;
00088   _height = height;
00089 }
00090 
00091 ////////////////////////////////////////////////////////////////////
00092 //     Function: GtkStatsLabel::Destructor
00093 //       Access: Public
00094 //  Description:
00095 ////////////////////////////////////////////////////////////////////
00096 GtkStatsLabel::
00097 ~GtkStatsLabel() {
00098   //  DeleteObject(_bg_brush);
00099 }
00100 
00101 ////////////////////////////////////////////////////////////////////
00102 //     Function: GtkStatsLabel::get_widget
00103 //       Access: Public
00104 //  Description: Returns the widget for this label.
00105 ////////////////////////////////////////////////////////////////////
00106 GtkWidget *GtkStatsLabel::
00107 get_widget() const {
00108   return _widget;
00109 }
00110 
00111 ////////////////////////////////////////////////////////////////////
00112 //     Function: GtkStatsLabel::get_height
00113 //       Access: Public
00114 //  Description: Returns the height of the label as we requested it.
00115 ////////////////////////////////////////////////////////////////////
00116 int GtkStatsLabel::
00117 get_height() const {
00118   return _height;
00119 }
00120 
00121 ////////////////////////////////////////////////////////////////////
00122 //     Function: GtkStatsLabel::get_collector_index
00123 //       Access: Public
00124 //  Description: Returns the collector this label represents.
00125 ////////////////////////////////////////////////////////////////////
00126 int GtkStatsLabel::
00127 get_collector_index() const {
00128   return _collector_index;
00129 }
00130 
00131 ////////////////////////////////////////////////////////////////////
00132 //     Function: GtkStatsLabel::set_highlight
00133 //       Access: Public
00134 //  Description: Enables or disables the visual highlight for this
00135 //               label.
00136 ////////////////////////////////////////////////////////////////////
00137 void GtkStatsLabel::
00138 set_highlight(bool highlight) {
00139   if (_highlight != highlight) {
00140     _highlight = highlight;
00141     gtk_widget_queue_draw(_widget);
00142   }
00143 }
00144 
00145 ////////////////////////////////////////////////////////////////////
00146 //     Function: GtkStatsLabel::get_highlight
00147 //       Access: Public
00148 //  Description: Returns true if the visual highlight for this
00149 //               label is enabled.
00150 ////////////////////////////////////////////////////////////////////
00151 bool GtkStatsLabel::
00152 get_highlight() const {
00153   return _highlight;
00154 }
00155 
00156 ////////////////////////////////////////////////////////////////////
00157 //     Function: GtkStatsLabel::set_mouse_within
00158 //       Access: Private
00159 //  Description: Used internally to indicate whether the mouse is
00160 //               within the label's widget.
00161 ////////////////////////////////////////////////////////////////////
00162 void GtkStatsLabel::
00163 set_mouse_within(bool mouse_within) {
00164   if (_mouse_within != mouse_within) {
00165     _mouse_within = mouse_within;
00166     gtk_widget_queue_draw(_widget);
00167   }
00168 }
00169 
00170 ////////////////////////////////////////////////////////////////////
00171 //     Function: GtkStatsLabel::expose_event_callback
00172 //       Access: Private, Static
00173 //  Description: Draws the background color of the label.
00174 ////////////////////////////////////////////////////////////////////
00175 gboolean GtkStatsLabel::
00176 expose_event_callback(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
00177   GtkStatsLabel *self = (GtkStatsLabel *)data;
00178 
00179   GdkGC *gc = gdk_gc_new(widget->window);
00180   gdk_gc_set_rgb_fg_color(gc, &self->_bg_color);
00181 
00182   gdk_draw_rectangle(widget->window, gc, TRUE, 0, 0, 
00183          widget->allocation.width, widget->allocation.height);
00184 
00185   // Center the text within the rectangle.
00186   int width, height;
00187   pango_layout_get_pixel_size(self->_layout, &width, &height);
00188 
00189   gdk_gc_set_rgb_fg_color(gc, &self->_fg_color);
00190   gdk_draw_layout(widget->window, gc, 
00191       (widget->allocation.width - width) / 2, 0,
00192       self->_layout);
00193 
00194   // Now draw the highlight rectangle, if any.
00195   if (self->_highlight || self->_mouse_within) {
00196     gdk_draw_rectangle(widget->window, gc, FALSE, 0, 0, 
00197            widget->allocation.width - 1, widget->allocation.height - 1);
00198   }
00199 
00200   g_object_unref(gc);
00201   return TRUE;
00202 }
00203 
00204 ////////////////////////////////////////////////////////////////////
00205 //     Function: GtkStatsLabel::enter_notify_event_callback
00206 //       Access: Private, Static
00207 //  Description: Called when the mouse enters the label region
00208 ////////////////////////////////////////////////////////////////////
00209 gboolean GtkStatsLabel::
00210 enter_notify_event_callback(GtkWidget *widget, GdkEventCrossing *event, 
00211           gpointer data) {
00212   GtkStatsLabel *self = (GtkStatsLabel *)data;
00213   self->set_mouse_within(true);
00214   return TRUE;
00215 }
00216  
00217 ////////////////////////////////////////////////////////////////////
00218 //     Function: GtkStatsLabel::leave_notify_event_callback
00219 //       Access: Private, Static
00220 //  Description: Called when the mouse leaves the label region
00221 ////////////////////////////////////////////////////////////////////
00222 gboolean GtkStatsLabel::
00223 leave_notify_event_callback(GtkWidget *widget, GdkEventCrossing *event, 
00224           gpointer data) {
00225   GtkStatsLabel *self = (GtkStatsLabel *)data;
00226   self->set_mouse_within(false);
00227   return TRUE;
00228 }
00229 
00230 ////////////////////////////////////////////////////////////////////
00231 //     Function: GtkStatsLabel::button_press_event_callback
00232 //       Access: Private, Static
00233 //  Description: Called when the mouse button is depressed within the
00234 //               label.
00235 ////////////////////////////////////////////////////////////////////
00236 gboolean GtkStatsLabel::
00237 button_press_event_callback(GtkWidget *widget, GdkEventButton *event, 
00238           gpointer data) {
00239   GtkStatsLabel *self = (GtkStatsLabel *)data;
00240   bool double_click = (event->type == GDK_2BUTTON_PRESS);
00241   if (double_click) {
00242     self->_graph->clicked_label(self->_collector_index);
00243   }
00244   return TRUE;
00245 }
 All Classes Functions Variables Enumerations