Panda3D
|
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 }