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 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 <gtk/gtkcellrenderer.h> 00028 #include <glib-object.h> 00029 00030 #include <algorithm> 00031 #include <cstring> 00032 #include <cstdio> 00033 00034 namespace fawkes { 00035 #if 0 /* just to make Emacs auto-indent happy */ 00036 } 00037 #endif 00038 00039 /** @class TwoLinesCellRenderer <gui_utils/twolines_cellrenderer.h> 00040 * Gtk cell renderer for two lines of text in a cell. 00041 * This cell renderer allows you to have two lines of text in a single 00042 * cell. It works by getting the text via two properties. The first line is 00043 * the primary line and printed "normally". The second line is the secondary 00044 * line and printed with a slightly smaller font. 00045 * @author Tim Niemueller 00046 */ 00047 00048 /** Constructor. */ 00049 TwoLinesCellRenderer::TwoLinesCellRenderer() 00050 : Glib::ObjectBase(typeid(TwoLinesCellRenderer)), 00051 Gtk::CellRenderer() 00052 #ifdef GLIBMM_PROPERTIES_ENABLED 00053 , __property_line1(*this, "line1", "") 00054 , __property_line2(*this, "line2", "") 00055 , __property_line2_enabled(*this, "line2_enabled", true) 00056 #endif 00057 { 00058 } 00059 00060 /** Destructor. */ 00061 TwoLinesCellRenderer::~TwoLinesCellRenderer() 00062 { 00063 } 00064 00065 00066 #ifdef GLIBMM_PROPERTIES_ENABLED 00067 /** Get property proxy for first line. 00068 * @return property proxy for first line 00069 */ 00070 Glib::PropertyProxy<Glib::ustring> 00071 TwoLinesCellRenderer::property_line1() 00072 { 00073 return __property_line1.get_proxy(); 00074 } 00075 00076 00077 /** Get property proxy for second line. 00078 * @return property proxy for second line 00079 */ 00080 Glib::PropertyProxy<Glib::ustring> 00081 TwoLinesCellRenderer::property_line2() 00082 { 00083 return __property_line2.get_proxy(); 00084 } 00085 00086 00087 /** Get property proxy that indicates whether the second line is enabled. 00088 * @return property proxy that indicates whether the second line is enabled 00089 */ 00090 Glib::PropertyProxy<bool> 00091 TwoLinesCellRenderer::property_line2_enabled() 00092 { 00093 return __property_line2_enabled.get_proxy(); 00094 } 00095 #endif 00096 00097 00098 /** Get required size for cell. 00099 * @param widget widget 00100 * @param cell_area area of the cell 00101 * @param x_offset ignored 00102 * @param y_offset ignored 00103 * @param width upon return contains the required width of the cell 00104 * @param height upon return contains the required height of the cell 00105 */ 00106 void 00107 TwoLinesCellRenderer::get_size_vfunc(Gtk::Widget &widget, 00108 const Gdk::Rectangle *cell_area, 00109 int *x_offset, int *y_offset, 00110 int *width, int *height) const 00111 { 00112 #ifdef GLIBMM_PROPERTIES_ENABLED 00113 // Compute text width 00114 Glib::RefPtr<Pango::Layout> layout_ptr = widget.create_pango_layout(__property_line1); 00115 Pango::Rectangle rect = layout_ptr->get_pixel_logical_extents(); 00116 00117 int line1_width = property_xpad() * 2 + rect.get_width(); 00118 int line1_height = property_ypad() * 2 + rect.get_height(); 00119 int line2_height; 00120 00121 if (__property_line2_enabled.get_value()) { 00122 Glib::RefPtr<Pango::Layout> layout2 = widget.create_pango_layout(__property_line2); 00123 Glib::RefPtr<Gtk::Style> style = widget.get_style(); 00124 Pango::FontDescription font2 = style->get_font(); 00125 font2.set_size((int)roundf(Pango::SCALE_SMALL * font2.get_size())); 00126 layout2->set_font_description(font2); 00127 Pango::Rectangle rect2 = layout2->get_pixel_logical_extents(); 00128 layout2->set_ellipsize(Pango::ELLIPSIZE_END); 00129 00130 line2_height = property_ypad() * 2 + rect2.get_height(); 00131 } else { 00132 line2_height = 0; 00133 } 00134 00135 if ( width ) *width = line1_width; 00136 if ( height ) *height = line1_height + 4 + line2_height; 00137 #endif 00138 } 00139 00140 00141 /** Render the cell. 00142 * This is called to render the cell. 00143 * @param window window 00144 * @param widget widget 00145 * @param background_area dimensions of the background area 00146 * @param cell_area dimensions of the cell area 00147 * @param expose_area dimensions of the exposed area 00148 * @param flags render flags 00149 */ 00150 void 00151 TwoLinesCellRenderer::render_vfunc(const Glib::RefPtr<Gdk::Drawable> &window, 00152 Gtk::Widget &widget, 00153 const Gdk::Rectangle &background_area, 00154 const Gdk::Rectangle &cell_area, 00155 const Gdk::Rectangle &expose_area, 00156 Gtk::CellRendererState flags) 00157 { 00158 #ifdef GLIBMM_PROPERTIES_ENABLED 00159 // Get cell size 00160 int x_offset = 0, y_offset = 0, width = 0, height = 0; 00161 get_size(widget, cell_area, x_offset, y_offset, width, height); 00162 00163 // Create the graphic context 00164 Glib::RefPtr<Gdk::GC> gc = Gdk::GC::create(window); 00165 00166 // Get cell state 00167 //Gtk::StateType state; 00168 Gtk::StateType text_state; 00169 if ((flags & Gtk::CELL_RENDERER_SELECTED) != 0) { 00170 //state = Gtk::STATE_SELECTED; 00171 text_state = (widget.has_focus()) ? Gtk::STATE_SELECTED : Gtk::STATE_ACTIVE; 00172 } else { 00173 //state = Gtk::STATE_NORMAL; 00174 text_state = (widget.is_sensitive()) ? Gtk::STATE_NORMAL : Gtk::STATE_INSENSITIVE; 00175 } 00176 00177 // Draw color text 00178 Glib::RefPtr<Gdk::Window> win = Glib::RefPtr<Gdk::Window>::cast_dynamic(window); 00179 Glib::RefPtr<Pango::Layout> layout_ptr = widget.create_pango_layout(__property_line1); 00180 Pango::Rectangle rect1 = layout_ptr->get_pixel_logical_extents(); 00181 widget.get_style()->paint_layout (win, text_state, true, cell_area, 00182 widget, "cellrenderertext", 00183 cell_area.get_x() + x_offset + 2 * property_xpad(), 00184 cell_area.get_y() + y_offset + 2 * property_ypad(), 00185 layout_ptr); 00186 00187 if (__property_line2_enabled.get_value()) { 00188 Glib::RefPtr<Pango::Layout> layout2 = widget.create_pango_layout(__property_line2); 00189 Glib::RefPtr<Gtk::Style> style = widget.get_style(); 00190 Pango::FontDescription font2 = style->get_font(); 00191 font2.set_size((int)roundf(Pango::SCALE_SMALL * std::max(font2.get_size(), 8))); 00192 layout2->set_font_description(font2); 00193 //Pango::Rectangle rect2 = layout2->get_pixel_logical_extents(); 00194 layout2->set_ellipsize(Pango::ELLIPSIZE_END); 00195 layout2->set_width((cell_area.get_width() - property_xpad()) * Pango::SCALE); 00196 widget.get_style()->paint_layout (win, text_state, true, cell_area, 00197 widget, "cellrenderertext", 00198 cell_area.get_x() + x_offset + property_xpad(), 00199 cell_area.get_y() + y_offset + property_ypad() + rect1.get_height() + 4, 00200 layout2); 00201 } 00202 #endif 00203 } 00204 00205 00206 } // end namespace fawkes