Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * twolines_cellrenderer.cpp - Gtk rell renderer for two lines of text 00004 * 00005 * Created: Sat Nov 29 16:36:41 2008 00006 * Copyright 2008-2011 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include <gui_utils/twolines_cellrenderer.h> 00025 00026 #include <gtkmm.h> 00027 #include <glib-object.h> 00028 00029 #include <algorithm> 00030 #include <cstring> 00031 #include <cstdio> 00032 00033 namespace fawkes { 00034 #if 0 /* just to make Emacs auto-indent happy */ 00035 } 00036 #endif 00037 00038 /** @class TwoLinesCellRenderer <gui_utils/twolines_cellrenderer.h> 00039 * Gtk cell renderer for two lines of text in a cell. 00040 * This cell renderer allows you to have two lines of text in a single 00041 * cell. It works by getting the text via two properties. The first line is 00042 * the primary line and printed "normally". The second line is the secondary 00043 * line and printed with a slightly smaller font. 00044 * @author Tim Niemueller 00045 */ 00046 00047 /** Constructor. */ 00048 TwoLinesCellRenderer::TwoLinesCellRenderer() 00049 : Glib::ObjectBase(typeid(TwoLinesCellRenderer)), 00050 Gtk::CellRenderer() 00051 #ifdef GLIBMM_PROPERTIES_ENABLED 00052 , __property_line1(*this, "line1", "") 00053 , __property_line2(*this, "line2", "") 00054 , __property_line2_enabled(*this, "line2_enabled", true) 00055 #endif 00056 { 00057 } 00058 00059 /** Destructor. */ 00060 TwoLinesCellRenderer::~TwoLinesCellRenderer() 00061 { 00062 } 00063 00064 00065 #ifdef GLIBMM_PROPERTIES_ENABLED 00066 /** Get property proxy for first line. 00067 * @return property proxy for first line 00068 */ 00069 Glib::PropertyProxy<Glib::ustring> 00070 TwoLinesCellRenderer::property_line1() 00071 { 00072 return __property_line1.get_proxy(); 00073 } 00074 00075 00076 /** Get property proxy for second line. 00077 * @return property proxy for second line 00078 */ 00079 Glib::PropertyProxy<Glib::ustring> 00080 TwoLinesCellRenderer::property_line2() 00081 { 00082 return __property_line2.get_proxy(); 00083 } 00084 00085 00086 /** Get property proxy that indicates whether the second line is enabled. 00087 * @return property proxy that indicates whether the second line is enabled 00088 */ 00089 Glib::PropertyProxy<bool> 00090 TwoLinesCellRenderer::property_line2_enabled() 00091 { 00092 return __property_line2_enabled.get_proxy(); 00093 } 00094 #endif 00095 00096 00097 #if GTK_VERSION_GE(3,0) 00098 /** Get required size for widget. 00099 * @param widget widget to create Pango layouts from 00100 * @param width upon return contains the required width 00101 * @param height upon return contains the required height 00102 */ 00103 void 00104 TwoLinesCellRenderer::get_size(Gtk::Widget &widget, 00105 int *width, int *height) const 00106 #else 00107 /** Get required size for cell. 00108 * @param widget widget 00109 * @param cell_area area of the cell 00110 * @param x_offset ignored 00111 * @param y_offset ignored 00112 * @param width upon return contains the required width of the cell 00113 * @param height upon return contains the required height of the cell 00114 */ 00115 void 00116 TwoLinesCellRenderer::get_size_vfunc(Gtk::Widget &widget, 00117 const Gdk::Rectangle *cell_area, 00118 int *x_offset, int *y_offset, 00119 int *width, int *height) const 00120 #endif 00121 { 00122 #ifdef GLIBMM_PROPERTIES_ENABLED 00123 // Compute text width 00124 Glib::RefPtr<Pango::Layout> layout_ptr = widget.create_pango_layout(__property_line1); 00125 Pango::Rectangle rect = layout_ptr->get_pixel_logical_extents(); 00126 00127 int line1_width = property_xpad() * 2 + rect.get_width(); 00128 int line1_height = property_ypad() * 2 + rect.get_height(); 00129 int line2_height; 00130 00131 if (__property_line2_enabled.get_value()) { 00132 Glib::RefPtr<Pango::Layout> layout2 = widget.create_pango_layout(__property_line2); 00133 #if GTK_VERSION_GE(3,0) 00134 Pango::FontDescription font2("sans 10"); 00135 #else 00136 Glib::RefPtr<Gtk::Style> style = widget.get_style(); 00137 Pango::FontDescription font2 = style->get_font(); 00138 #endif 00139 00140 font2.set_size((int)roundf(Pango::SCALE_SMALL * font2.get_size())); 00141 layout2->set_font_description(font2); 00142 Pango::Rectangle rect2 = layout2->get_pixel_logical_extents(); 00143 layout2->set_ellipsize(Pango::ELLIPSIZE_END); 00144 00145 line2_height = property_ypad() * 2 + rect2.get_height(); 00146 } else { 00147 line2_height = 0; 00148 } 00149 00150 if (width) *width = line1_width; 00151 if (height) *height = line1_height + 4 + line2_height; 00152 #endif 00153 } 00154 00155 #if GTK_VERSION_GE(3,0) 00156 /** Get required size for cell. 00157 * @param widget widget 00158 * @param minimum_width upon return contains the required width of the cell 00159 * @param natural_width upon return contains the required width of the cell 00160 */ 00161 void 00162 TwoLinesCellRenderer::get_preferred_width_vfunc(Gtk::Widget &widget, 00163 int &minimum_width, 00164 int &natural_width) const 00165 { 00166 int width = 0; 00167 get_size(widget, &width, NULL); 00168 minimum_width = natural_width = width; 00169 } 00170 00171 /** Get required size for cell. 00172 * @param widget widget 00173 * @param minimum_height upon return contains the required height of the cell 00174 * @param natural_height upon return contains the required height of the cell 00175 */ 00176 void 00177 TwoLinesCellRenderer::get_preferred_height_vfunc(Gtk::Widget &widget, 00178 int &minimum_height, 00179 int &natural_height) const 00180 { 00181 int height = 0; 00182 get_size(widget, NULL, &height); 00183 minimum_height = natural_height = height; 00184 } 00185 #endif 00186 00187 #if GTK_VERSION_GE(3,0) 00188 /** Render the cell. 00189 * This is called to render the cell. 00190 * @param cr graphic context to use for drawing 00191 * @param widget widget 00192 * @param background_area dimensions of the background area 00193 * @param cell_area dimensions of the cell area 00194 * @param flags render flags 00195 */ 00196 void 00197 TwoLinesCellRenderer::render_vfunc(const Cairo::RefPtr<Cairo::Context> &cr, 00198 Gtk::Widget &widget, 00199 const Gdk::Rectangle &background_area, 00200 const Gdk::Rectangle &cell_area, 00201 Gtk::CellRendererState flags) 00202 #else 00203 /** Render the cell. 00204 * This is called to render the cell. 00205 * @param window window 00206 * @param widget widget 00207 * @param background_area dimensions of the background area 00208 * @param cell_area dimensions of the cell area 00209 * @param expose_area dimensions of the exposed area 00210 * @param flags render flags 00211 */ 00212 void 00213 TwoLinesCellRenderer::render_vfunc(const Glib::RefPtr<Gdk::Drawable> &window, 00214 Gtk::Widget &widget, 00215 const Gdk::Rectangle &background_area, 00216 const Gdk::Rectangle &cell_area, 00217 const Gdk::Rectangle &expose_area, 00218 Gtk::CellRendererState flags) 00219 #endif 00220 { 00221 #ifdef GLIBMM_PROPERTIES_ENABLED 00222 // Get cell size 00223 int x_offset = 0, y_offset = 0; 00224 #if GTK_VERSION_LT(3,0) 00225 int width = 0, height = 0; 00226 get_size(widget, cell_area, x_offset, y_offset, width, height); 00227 00228 // Get cell state 00229 //Gtk::StateType state; 00230 Gtk::StateType text_state; 00231 if ((flags & Gtk::CELL_RENDERER_SELECTED) != 0) { 00232 //state = Gtk::STATE_SELECTED; 00233 text_state = (widget.has_focus()) ? Gtk::STATE_SELECTED : Gtk::STATE_ACTIVE; 00234 } else { 00235 //state = Gtk::STATE_NORMAL; 00236 text_state = (widget.is_sensitive()) ? Gtk::STATE_NORMAL : Gtk::STATE_INSENSITIVE; 00237 } 00238 00239 // Draw color text 00240 Glib::RefPtr<Gdk::Window> win = 00241 Glib::RefPtr<Gdk::Window>::cast_dynamic(window); 00242 #endif 00243 Glib::RefPtr<Pango::Layout> layout_ptr = 00244 widget.create_pango_layout(__property_line1); 00245 Pango::Rectangle rect1 = layout_ptr->get_pixel_logical_extents(); 00246 #if GTK_VERSION_GE(3,0) 00247 cr->move_to(cell_area.get_x() + x_offset + 2 * property_xpad(), 00248 cell_area.get_y() + y_offset + 2 * property_ypad()); 00249 layout_ptr->show_in_cairo_context(cr); 00250 #else 00251 widget.get_style()->paint_layout(win, text_state, true, cell_area, 00252 widget, "cellrenderertext", 00253 cell_area.get_x() + x_offset + 2 * property_xpad(), 00254 cell_area.get_y() + y_offset + 2 * property_ypad(), 00255 layout_ptr); 00256 #endif 00257 00258 if (__property_line2_enabled.get_value()) { 00259 Glib::RefPtr<Pango::Layout> layout2 = 00260 widget.create_pango_layout(__property_line2); 00261 #if GTK_VERSION_GE(3,0) 00262 Pango::FontDescription font2("sans 10"); 00263 #else 00264 Glib::RefPtr<Gtk::Style> style = widget.get_style(); 00265 Pango::FontDescription font2 = style->get_font(); 00266 #endif 00267 font2.set_size((int)roundf(Pango::SCALE_SMALL * font2.get_size())); 00268 layout2->set_font_description(font2); 00269 //Pango::Rectangle rect2 = layout2->get_pixel_logical_extents(); 00270 layout2->set_ellipsize(Pango::ELLIPSIZE_END); 00271 layout2->set_width((cell_area.get_width() - property_xpad()) * Pango::SCALE); 00272 00273 #if GTK_VERSION_GE(3,0) 00274 cr->move_to(cell_area.get_x() + x_offset + property_xpad(), 00275 cell_area.get_y() + y_offset + property_ypad() + 00276 rect1.get_height() + 4); 00277 layout2->show_in_cairo_context(cr); 00278 #else 00279 widget.get_style()->paint_layout (win, text_state, true, cell_area, 00280 widget, "cellrenderertext", 00281 cell_area.get_x() + x_offset + property_xpad(), 00282 cell_area.get_y() + y_offset + property_ypad() + rect1.get_height() + 4, 00283 layout2); 00284 #endif 00285 } 00286 #endif 00287 } 00288 00289 00290 } // end namespace fawkes